【发布时间】:2015-01-22 14:46:19
【问题描述】:
我一直在到处寻找这个问题的答案,但我无法让它发挥作用。
我有一个使用 Perl 读入数组的输入文件。该文件是一个包含表格的文本文件。 Perl 将它作为一个数组读入,每个元素都是一整行(包括所有五列)。这是数组的样子:
0__len__340 16 324 0 0.0470588235294118
1__len__251 2 249 0 0.00796812749003984
2__len__497 0 497 0 0
3__len__55 7 48 0 0.127272727272727
4__len__171 0 171 0 0
5__len__75 0 75 0 0
6__len__160 75 85 0 0.46875
7__len__285 1 284 0 0.00350877192982456
8__len__94 44 50 0 0.468085106382979
我需要按最后一列的降序对该表进行排序。所以我的输出应该是:
6__len__160 75 85 0 0.46875
8__len__94 44 50 0 0.468085106382979
3__len__55 7 48 0 0.127272727272727
0__len__340 16 324 0 0.0470588235294118
1__len__251 2 249 0 0.00796812749003984
7__len__285 1 284 0 0.00350877192982456
2__len__497 0 497 0 0
4__len__171 0 171 0 0
5__len__75 0 75 0 0
我尝试了几种方法,但都没有奏效。这是我尝试过的代码:
@input = <FILENAME>;
#Close the file
close FILENAME;
my @fractions;
my $y = 0;
for (my $x = 1; $x <= $#input; ++$x) {
$fractions[$y] = (split (/\s/, $input[$x]))[4];
++$y;
}
my @sorted = sort {$b <=> $a} @fractions;
my $e = 1;
my $z = 0;
my $f = 0;
my @final;
do {
do {
if ((split (/\s/, $input[$e]))[4] == $sorted[$z]){
$final[$f] = $input[$e];
++$e;
++$f;
} else {
++$e;
}
} until ($e > $#input);
do {
++$z;
} until ($sorted[$z] != $sorted[$z - 1]);
$e = 0;
} until ($z > $#sorted);
for (my $h = 0; $h <= $#final; ++$h) {
print $final[$h] . "\n\n";
}
有了这个,我基本上是尝试将第5列的数字放入自己的数组中,排序,然后回过原数组,拉出与排序后的数组匹配的元素,放入最终的数组中.
如果我继续努力,这可能会奏效,但运行时间太长以至于不切实际。我用来测试我的代码的这个小表需要很长时间才能运行,一旦代码运行,它将处理一个包含数百万行的表。
我也尝试将排序命令应用于表本身,但我的输出与我的输入完全相同...它没有得到排序。
@input = <FILENAME>;
close FILENAME;
my @sorted = sort { $b->[4] <=> $a->[4] } @input;
for (my $h = 0; $h <= $#sorted; ++$h) {
print $sorted[$h] . "\n\n";
}
exit;
最后,我尝试将数组放入哈希表中,其中键是前四列,因为第一列名称是唯一的,而值是第五列。
然后我希望我可以按值对哈希进行排序,并且键将保留其分配的值。我也无法让它工作,但不幸的是几天前我删除了代码。
一个问题是我无法弄清楚如何只在第五列之前拆分字符串,所以我最终得到了两个字符串,一个包含前四列,一个包含第五列。
我对排序命令做错了什么?有没有更好的方法来做到这一点?
【问题讨论】:
-
“便携式”紧急情况时不在 Unix 上排序 :-)
perl -E 'say sort { (split(/\s+/,$b))[4] <=> (split(/\s+/,$a))[4] } <>'
标签: arrays string perl sorting data-structures