如何在Perl中对数字进行排序

24
print "@_\n";
4109 4121 6823 12967 12971 14003 20186

我该如何在Perl中对其进行排序?

使用@sorted = sort(@_);会按字母顺序排序:

13041 13045 14003 20186 4109 4121 6823

我该如何进行数字排序?Perl 是否有内置的归并排序、插入排序等函数?

7个回答

50

你可以向 Perl 的排序程序传递自定义的比较函数。只需使用:

@sorted = sort { $a <=> $b } @unsorted;
< p > sort函数接受一个自定义比较函数作为其第一个参数,形式为代码块。 {...}部分只是这个代码块(参见http://perldoc.perl.org/functions/sort.html)。

sort会在需要比较要排序的数组中的两个元素时调用此自定义比较函数。 sort始终将要比较的两个值传递为$a$b,并且比较函数必须返回比较结果。 在这种情况下,它只使用数字比较运算符(请参见http://perldoc.perl.org/perlop.html#Equality-Operators),这可能是为了这个目的而创建的:-)。

解决方案无耻地从“Perl Cookbook”,第04章子章节15中窃取(购买这本书-它很值得!)


1
我会把那个链接删除,因为它在未经版权所有者同意的情况下传播了受版权保护的材料。你可以推荐原作(《Perl烹饪书》,Christiansen和Torkington)来替代。 - Philip Potter
在 [Perl] 标签下,似乎有一个共识,即链接盗版的 O'Reilly 图书(或任何图书)是不好的。需要进行编辑以删除这些内容。 - DVK
抱歉,我没有意识到链接是盗版材料。感谢您的修复。 - sleske
谷歌图书经常有适合链接的好的非盗版材料。 - daotoad

11

sort() 函数提供一个比较函数:

# sort numerically ascending
my @articles = sort {$a <=> $b} @files;

# sort numerically descending
my @articles = sort {$b <=> $a} @files;

默认排序函数是cmp,它进行字符串比较,会将(1, 2, 10)排列成(1, 10, 2)<=>是数值比较运算符,如上所示。


8

Perl的sort默认按ASCII顺序进行字母排序。若要按数字排序,可以使用以下方法:

@sorted = sort { $a <=> $b } @_;

1
@Lazer:请看我的解释(我提交了相同的答案,只是稍后一点而已;-)。 - sleske

6

5
@l = (4109, 4121, 6823, 12967, 12971, 14003, 20186, 1, 3, 4);
@l = sort { $a <=> $b } @l;
print "@l\n"; # 1 3 4 4109 4121 6823 12967 12971 14003 20186

你需要提供自己的排序子程序 { $a <=> $b }


{ $a <=> $b } 是什么?是匿名函数吗?请在回答中详细解释一下。 - Peter Mortensen
抱歉,我已经忘记了我曾经对Perl的所有了解。似乎它被称为“块”,而a/b变量是在使用该块时sort提供的“包全局”变量。 - ase
@PeterMortensen你在他们写完答案十年后要求他们详细阐述,而那个答案并不是被采纳的;你确定这是最好的利用你或他们的时间吗?(是的,我意识到讽刺之处,三年后才指责你) - Diablo-D3
@PeterMortensen,你在十年后要求某人对他们写的答案进行详细阐述,而那个答案并不是被接受的答案;你确定这是你或他们时间的最佳利用吗?(是的,我意识到现在才对此事进行指责有些讽刺) - undefined

3
你可以预定义一个函数,用于比较数组中的值。 perldoc -f sort 给出了一个示例:
# Sort using explicit subroutine name
sub byage {
   $age{$a} <=> $age{$b};  # Presuming numeric
}
@sortedclass = sort byage @class;
<=> 运算符用于数字排序。
@sorted = sort {$a <=> $b} @unsorted;

1
你会在这里(以及许多其他地方)发现,对数字数组进行排序的方法是:
@sorted_array = sort { $a <=> $b } @unsorted_array;

现在你尝试一下,却出现一个错误:"Can't use "my $a" in sort comparison"!(这是因为你已经使用了'strict.pm'声明了'$a')。但是,你也不能使用未声明的变量,因为它们将被拒绝为未定义!所以,你可能会感到陷入了僵局。 perldoc.perl.org和其他大多数地方都没有提到'$a'和'$b'是保留的(令牌)用于此用途!(当然,这是在使用'strict'时,应该这样做。而这相当疯狂,因为'a'和'b'是编程中使用最普遍的短变量之一,逻辑上也是如此!)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接