List 在perl中对列表排序时出现问题

List 在perl中对列表排序时出现问题,list,perl,sorting,comparison,List,Perl,Sorting,Comparison,我有一个表示时间值的字符串列表,即1us、100ps、10s、7fs微秒、皮秒、秒、飞秒等。 我需要按升序对列表进行排序。为此,我编写了一个比较例程,当给定两个字符串时,将每个字符串转换为相应的数值并进行比较。但是,列表的排序仍然不正确。经过多次调试,我不知所措。这是我的密码: #!/usr/bin/perl use warnings; use strict; my %scales = ('fs'=>1e-15,'ps'=>1e-12,'ns'=>1e-9,'us'=&g

我有一个表示时间值的字符串列表,即1us、100ps、10s、7fs微秒、皮秒、秒、飞秒等。 我需要按升序对列表进行排序。为此,我编写了一个比较例程,当给定两个字符串时,将每个字符串转换为相应的数值并进行比较。但是,列表的排序仍然不正确。经过多次调试,我不知所措。这是我的密码:

#!/usr/bin/perl
use warnings;
use strict;
   my %scales = ('fs'=>1e-15,'ps'=>1e-12,'ns'=>1e-9,'us'=>1e-6,'ms'=>1e-3,'s'=>1);
   my @times = ('1s','7ns','100ps','500ms','9us');
   my @stimes = sort bytime @times;
   sub bytime {

      my $op1 = $a;
      my $op2 = $b;
      $op1 =~ /\b(\d+)([munpf]*s)\b/;
      my $v1 = $1 * $scales{$2};
      $op2 =~ /\b(\d+)([munpf]*s)\b/;
      my $v2 = $1 * $scales{$2};
      return $v1 > $v2;
}

print "@times"."\n"."@stimes"."\n";
我得到的结果是:

1s 7ns 100ps 500ms 9us

100ps 7ns 500ms 1s 9us

这显然是错误的,即使进行了一些排序。
发生了什么事?

您的错误在线路上

return $v1 > $v2;
如果$v1大于$v2,则返回1 true;在所有其他情况下,返回0 false

您希望改为使用数值比较运算符:

输出:

1s 7ns 100ps 500ms 9us
100ps 7ns 9us 500ms 1s

你的错误就在这条线上

return $v1 > $v2;
如果$v1大于$v2,则返回1 true;在所有其他情况下,返回0 false

您希望改为使用数值比较运算符:

输出:

1s 7ns 100ps 500ms 9us
100ps 7ns 9us 500ms 1s

谢谢何时使用>?使用普通比较运算符==,!=,>=“西尔瓦”回答得很好。但是如果速度是一个问题,如果@times可能有数千个元素,那么您也应该使用这样的Schwartzian变换进行排序:my@stimes=map$$$\u0],sort{$$a[1]$$b[1]}map[$\u0,convert$\u0],@times;使用子转换{shift=~/\b\d+[munpf]*s\b/?$1*$scales{$2}:die}。这样,您将不会多次转换同一个数字。更多信息:谢谢。何时使用>?使用普通比较运算符==,!=,>=“西尔瓦”回答得很好。但是如果速度是一个问题,如果@times可能有数千个元素,那么您也应该使用这样的Schwartzian变换进行排序:my@stimes=map$$$\u0],sort{$$a[1]$$b[1]}map[$\u0,convert$\u0],@times;使用子转换{shift=~/\b\d+[munpf]*s\b/?$1*$scales{$2}:die}。这样,您将不会多次转换同一个数字。更多信息: