【问题标题】:Array of strings to float values can correctly sort negative numbers but same values using sprintf, kernel.format, etc. sort incorrectly浮点值的字符串数组可以正确排序负数,但使用 sprintf、kernel.format 等对相同的值排序不正确
【发布时间】:2014-10-09 00:29:21
【问题描述】:

为什么在使用 '%.3f' % string.to_float 或包括 sprintf、Kernel.format 在内的任何变体时,string.to_float 值的数组可以正确排序,但这些相同的值排序不正确?

我该如何纠正这个问题?

我目前正在处理一项挑战,它会为您提供一个文本文件,其中包含用数字填充的行(示例):

1.123 -3.010 3.999 -2.199 -1.212 2.190 4.121 0.000

我的目标是对这些数字进行排序,并按照它们的显示将它们打印到控制台。

我的第一次尝试是首先将这些行拆分为各自的字符串编号,然后使用 .to_f 将它们转换为浮点值,最后对它们进行排序并将它们重新连接在一起(空格分隔)。

看起来像这样:

line.chomp.split(" ").map { |e| e.to_f  }.sort!.join(" ")

这很有效,直到我意识到任何以小数点后三位精度结尾的数字(例如 68.060)都会丢失最后一个零。因此显示为 68.06 而不是 68.060,这会使解决方案无效。

我四处走走,果然找到了很多参考资料:

Kernel.format('%.3f', num)

sprintf '%.3f' % num

这些都很完美,他们解决了问题。我这样应用它们(尝试了变化,但它们都做了同样的事情):

line.chomp.split(" ").map { |e| sprintf '%.3f', e  }.sort!.join(" ")

然后我发现自己正在寻找另一个问题。放入控制台的每一行现在都将负数组织起来,就好像它们是正数一样,所以不是:

-3.010 -2.199 -1.212 0.000 1.123 2.190 3.999 4.121

在控制台上,我看到了:

-1.212 -2.199 -3.010 0.000 1.123 2.19 3.999 4.121

这个我找不到太多。这可能是我的错,因为我不知道在谷歌上放什么,但我的搜索都没有找到任何相关的东西。

【问题讨论】:

    标签: ruby arrays sorting printf floating-point-precision


    【解决方案1】:

    在将数组格式化为字符串数组之后对数组进行排序。这意味着您的数组是按字典顺序排列元素,而不是按数字排列。

    您应该首先将您的数组映射为浮点值,然后对其进行排序:

    line.chomp.split(" ").map(&:to_f).sort
    

    现在您可以适当地格式化数字:

    line.chomp.split(" ").map(&:to_f).sort.map { |e| sprintf '%.3f', e }.join(" ")
    

    【讨论】:

    • 我希望不必使用两张地图来完成它!谢谢!
    【解决方案2】:

    您在格式化后对它们进行排序,这会导致您对字符串而不是浮点数进行排序。只需先执行排序,然后映射到字符串 :)

    【讨论】:

      猜你喜欢
      • 2013-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多