perl :施瓦茨变换,多级排序:首先按照第一列排序,第一列相等
这篇文章的写成主要参考了ace_fei的内容,其中我认为有错误的地方,并进行了修改。网页如下:http://blog.csdn.net/ace_fei/article/details/7679609,大家可以到哪里去比较参考。 加入我们有这样一个文件,他的内容如下: 4 6 3 ? 当然可能更多,我们排序的规则如下: 首先按照第一列排序,如果第一列相等,那么就按照第二列进行排序,如果第二列相等就按照第三列的内容排序。 我们先把问题最简单化,把上述的数字放到一个数组中;然后进行排序; 程序如下: use strict; use warnings; my @num; my @out; my $out; my $num; @num=( [qw[4 6 3]],[qw[4 5 1]],[qw[1 2 3]],[qw[1 9 0]],[qw[2 0 5]],[qw[3 6 2]],[qw[2 0 8]],[qw[2 0 6]],); @out = sort {$a->[0] <=> $b->[0] or $a->[1] <=> $b->[1] or $a->[2] <=> $b->[2]} @num; for $out (@out) { print "@$outn"; } 得到的结果如下: C:WINDOWSsystem32cmd.exe /c perl "F:perlb.pl" 1 2 3 1 9 0 2 0 5 2 0 6 2 0 8 3 6 2 4 5 1 4 6 3 Hit any key to close this window... 当然你也可以按照第一列升序,如果第一列相同,第二列降序,如果第二列相同,第三列升序。 use warnings; my @num; my @out; my $out; my $num; @num=( [qw[4 6 3]],); @out = sort {$a->[0] <=> $b->[0] or $b->[1] <=> $a->[1] or $a->[2] <=> $b->[2]} @num; for $out (@out) { print "@$outn"; } 结果如下: C:WINDOWSsystem32cmd.exe /c perl "F:perlb.pl" 1 9 0 1 2 3 2 0 5 2 0 6 2 0 8 3 6 2 4 6 3 4 5 1 Hit any key to close this window... 当然我们要处理的东西,一般都不会直接放在数组中,而是一个放在一个文件中,我们就要先对文件进行处理; 现在我们把 4 6 3 放入一个dna.txt的文件夹中 程序如下: use strict; use warnings; my @out; my $out; open(IN,"f:perldna.txt") || die("can not open"); @out = sort {$a->[0] <=> $b->[0] or $b->[1] <=> $a->[1] or $a->[2] <=> $b->[2]} map [(split)],<IN>; for $out(@out) { print "@$outn"; } 这里和ace fei有很大的不同,我不知道他们最后的结果是怎么得出来的。 因为我用那个程序得出的结果一直是不正确的 我们先来看一下正确的结果: C:WINDOWSsystem32cmd.exe /c perl "F:perlb.pl" 1 9 0 1 2 3 2 0 5 2 0 6 2 0 8 3 6 2 4 6 3 4 5 1 Hit any key to close this window... 我们再来分析一下ace fei的程序; use strict; use warnings; my @out; my $out; open(IN,"f:perldna.txt") || die("can not open"); @out = sort {$a->[0] <=> $b->[0] or $b->[1] <=> $a->[1] or $a->[2] <=> $b->[2]} map [$_,(split)],<IN>; for $out(@out) { print "@$outn"; } 两者的不同点在于map后面的内容,我修改以后中括号内只留下了(split),因为如果有$_也留下的话,程序会报错,并且都是双行显示。 如下: C:WINDOWSsystem32cmd.exe /c perl "F:perlb.pl" Argument "4 5 1n" isn't numeric in numeric comparison (<=>) at F:perlb.pl li e 9,<IN> line 8. Argument "4 6 3n" isn't numeric in numeric comparison (<=>) at F:perlb.pl li e 9,<IN> line 8. Argument "1 9 0n" isn't numeric in numeric comparison (<=>) at F:perlb.pl li e 9,<IN> line 8. Argument "1 2 3n" isn't numeric in numeric comparison (<=>) at F:perlb.pl li e 9,<IN> line 8. Argument "3 6 2n" isn't numeric in numeric comparison (<=>) at F:perlb.pl li e 9,<IN> line 8. Argument "2 0 5n" isn't numeric in numeric comparison (<=>) at F:perlb.pl li e 9,<IN> line 8. Argument "2 0 6n" isn't numeric in numeric comparison (<=>) at F:perlb.pl li e 9,<IN> line 8. Argument "2 0 8n" isn't numeric in numeric comparison (<=>) at F:perlb.pl li e 9,<IN> line 8. 1 2 3 1 2 3 1 9 0 1 9 0 2 0 5 2 0 5 2 0 8 2 0 8 2 0 6 2 0 6 3 6 2 3 6 2 4 5 1 4 5 1 4 6 3 4 6 3 Hit any key to close this window... 其实我们从最根本的结构上来分析,很容易得出结论: 这里只不过是sort的一个更复杂的用法, sort后面紧跟着的是你选择的排序方法,然后后面是数组,我们最后一个map的目的就是得出一个让sort可以用的数组 [split],<in>其实就是[split/s/,$_],<in>的缩写,我实在想不明白,他把$_放在前面是干什么的?并且加在前面也会导致重复输出。 我们按照[split/s/,<in>的写法看看, 程序如下: use strict; use warnings; my @out; my $out; open(IN,"f:perldna.txt") || die("can not open"); @out = sort {$a->[0] <=> $b->[0] or $b->[1] <=> $a->[1] or $a->[2] <=> $b->[2]} map [(split/s/,$_)],<IN>; for $out(@out) { print "@$outn"; }结果如下: C:WINDOWSsystem32cmd.exe /c perl "F:perlb.pl" 1 9 0 1 2 3 2 0 5 2 0 6 2 0 8 3 6 2 4 6 3 4 5 1 Hit any key to close this window... (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |