【问题标题】:Perl: Numerical sort of arrays in a hash 2 (Schwarzian Transform)Perl:哈希 2 中的数值排序数组(施瓦兹变换)
【发布时间】:2011-12-18 16:53:32
【问题描述】:

这其实是这个帖子的后续: Perl: Numerical sort of arrays in a hash

我无法编辑原始问题,因为我当前的代码有点不同,所以我只是将其作为另一个问题提出。

好的,使用 Schwarzian 变换后,我有了这个:

my @mylines =("0.899 0.92 cat", 
            "9.999 0.001 dog",
            "-0.52 0.3 humpty", 
            "13.52 0.09 bumbo",
            "-1.52 0.98 nanny",
            "3.52 0.34 lala");

my @sorted = map { join ' ', @$_ }
             reverse sort { $a->[0] cmp $b->[0] or $a->[1] <=> $b->[1] }
             map { [ split ] } (@mylines);

print "$_\n" for @sorted;

我希望输出首先按第一列排序,然后是第二列,但结果是这样的:

9.999 0.001 dog
3.52 0.34 lala
13.52 0.09 bumbo
0.899 0.92 cat
-1.52 0.98 nanny
-0.52 0.3 humpty

我想那是因为它正在对字符进行排序……但我需要对它进行数字排序。我是否需要在排序函数中的某处放置一个类似 java 的“parseInt()”?

【问题讨论】:

  • 不,你需要阅读“perldoc perlop”并注意cmp&lt;=&gt;之间的区别。
  • 我怀疑你会发现 ST 在这种情况下实际上会减慢速度。让你知道。

标签: arrays perl sorting numerical


【解决方案1】:

您在第一列上使用cmp。这意味着它将其排序为文本。您的排序功能应该是:

sort { $a->[0] <=> $b->[0] or $a->[1] <=> $b->[1] } ...

输出结果:

13.52 0.09 bumbo
9.999 0.001 dog
3.52 0.34 lala
0.899 0.92 cat
-0.52 0.3 humpty
-1.52 0.98 nanny

但是,您永远不需要在排序前添加reverse,因为您始终可以颠倒这些术语:

sort { $b->[0] <=> $a->[0] or $b->[1] <=> $a->[1] } ...

【讨论】:

  • 也有人会争辩说,最好始终使用reverse,因为这样可以更明显地表明您正在执行反向排序。另外,使用reverse 意味着在很多情况下您不必指定要用于排序的表达式。
  • @Jamessan - 虽然可读性是一个非常有效的问题,但在这种情况下,添加 O(N) 操作来反转数组可能成本太高而无法支付。最好添加注释说明 ba 是反向的)。
  • @DVK : According to hobbs 优化器理解reverse sort { $a &lt;=&gt; $b} 等同于sort { $a &lt;=&gt; $b }。我想这意味着不会产生额外的开销
  • @jamessan,由于每个字段都是单独排序的,所以前面有一个reverse 不会增加可读性。
  • @ikegami :我很好奇这种行为记录在哪里。从来没有在 perldoc 中遇到过它。似乎是一个很好的问题。
猜你喜欢
  • 2012-07-28
  • 2011-12-16
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 2014-10-27
  • 1970-01-01
  • 2012-01-21
  • 2012-12-07
相关资源
最近更新 更多