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

Yak*_*Dan 1 sorting perl comparison list

我有一个表示时间值的字符串列表,即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";
Run Code Online (Sandbox Code Playgroud)

我得到的结果是:

1s 7ns 100ps 500ms 9us

100ps 7ns 500ms 1s 9us

这显然是错误的,即使进行了一些排序.这是怎么回事?

Sil*_*var 7

你的错误就行了

return $v1 > $v2;
Run Code Online (Sandbox Code Playgroud)

如果$v1大于$v20(假)在所有其他情况下,它将返回1(真).

您想要使用数值比较运算符<=>:

return $v1 <=> $v2;
Run Code Online (Sandbox Code Playgroud)

它将返回1,0或-1,具体取决于比较结果,并允许排序正确地执行其工作.(如果你处理的是字符串而不是数字,那么运算符就是cmp.)

完整的工作代码:

#!/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";
Run Code Online (Sandbox Code Playgroud)

输出:

1s 7ns 100ps 500ms 9us
100ps 7ns 9us 500ms 1s
Run Code Online (Sandbox Code Playgroud)

  • 当你试图找出特定的数学方程或不等式是否成立时,你使用正常的比较运算符`==`,`!=`,`<`,`>`,`> =`和`<=` .它们返回真值或假值.排序需要三值比较,其中相同的运算符(或函数)可以返回1,0或-1,具体取决于两个项的顺序.`$ x <=> $ y`等于`$ x <$ y?-1:($ x> $ y?1:0)`. (2认同)