我想做sort(1)的逆操作:在 Perl 中将标准输入的每一行随机化到标准输出。
TheSnide
问问题
2238 次
3 回答
10
我敢打赌,真正的 Perl 黑客会撕毁它,但它仍然存在。
use strict;
use warnings;
use List::Util 'shuffle';
my @lines = ();
my $bufsize = 512;
while(<STDIN>) {
push @lines, $_;
if (@lines == $bufsize) {
print shuffle(@lines);
undef @lines;
}
}
print shuffle(@lines);
此解决方案与其他解决方案之间的区别:
- 不会消耗所有输入然后将其随机化(内存占用),但会随机化每个 $bufsize 行(与其他选项相比,不是真正随机且慢得像狗)。
- 使用一个返回新列表的模块,而不是就地编辑 Fisher - Yates 实现。它们是可互换的(除非您必须将打印与随机播放分开)。有关更多信息,请在您的 shell 上键入 perldoc -q rand。
于 2008-11-13T09:39:52.797 回答
6
这个 perl 片段可以解决问题:
#! /usr/bin/perl
# randomize cat
# fisher_yates_shuffle code copied from Perl Cookbook
# (By Tom Christiansen & Nathan Torkington; ISBN 1-56592-243-3)
use strict;
my @lines = <>;
fisher_yates_shuffle( \@lines ); # permutes @array in place
foreach my $line (@lines) {
print $line;
}
# fisher_yates_shuffle( \@array ) : generate a random permutation
# of @array in place
sub fisher_yates_shuffle {
my $array = shift;
my $i;
for ($i = @$array; --$i; ) {
my $j = int rand ($i+1);
next if $i == $j;
@$array[$i,$j] = @$array[$j,$i];
}
}
__END__
于 2008-11-13T09:36:58.760 回答
5
use List::Util 'shuffle';
print shuffle <>
或者如果你担心最后几行缺少\n,
chomp(my @lines = <>);
print "$_\n" for shuffle @lines;
于 2008-11-13T18:17:11.590 回答