要浮动值的字符串数组可以使用sprintf,kernel.format等正确排序负数但相同的值排序错误

时间:2014-10-09 00:29:22

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

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

我该如何纠正?

我目前正在开展一项挑战,为您提供一个包含数字行的文本文件(示例):

  

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

这个我找不到多少。这可能是我的错,因为我不知道究竟要把什么放在谷歌上,但我的搜索没有任何相关内容。

2 个答案:

答案 0 :(得分:1)

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

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

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

现在您可以正确格式化数字:

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

答案 1 :(得分:0)

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