perl :施瓦茨变换,多级排序:首先按照第一列排序,第一列相等的按照第二列排序............

这篇文章的写成主要参考了ace_fei的内容,其中我认为有错误的地方,并进行了修改。网页如下:http://blog.csdn.net/ace_fei/article/details/7679609,大家可以到哪里去比较参考。

加入我们有这样一个文件,他的内容如下:

4 6 3  
4 5 1  
1 2 3  
1 9 0  
2 0 5  
3 6 2  
2 0 8  
2 0 6 

当然可能更多,我们排序的规则如下:

首先按照第一列排序,如果第一列相等,那么就按照第二列进行排序,如果第二列相等就按照第三列的内容排序。

我们先把问题最简单化,把上述的数字放到一个数组中;然后进行排序;

程序如下:

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 "@$out\n";
}

得到的结果如下:


C:\WINDOWS\system32\cmd.exe /c perl "F:\perl\b.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]],
[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 $b->[1] <=> $a->[1]
		  or $a->[2] <=> $b->[2]} @num;
for $out (@out)
{
	print "@$out\n";
}

结果如下:

C:\WINDOWS\system32\cmd.exe /c perl "F:\perl\b.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
4 5 1
1 2 3
1 9 0
2 0 5
3 6 2
2 0 8
2 0 6

放入一个dna.txt的文件夹中

程序如下:

use strict;
use warnings;


my @out;
my $out;
open(IN,"f:\\perl\\dna.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 "@$out\n";
}

这里和ace fei有很大的不同,我不知道他们最后的结果是怎么得出来的。

因为我用那个程序得出的结果一直是不正确的

我们先来看一下正确的结果:

C:\WINDOWS\system32\cmd.exe /c perl "F:\perl\b.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:\\perl\\dna.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 "@$out\n";
}

两者的不同点在于map后面的内容,我修改以后中括号内只留下了(split),因为如果有$_也留下的话,程序会报错,并且都是双行显示。

如下:

C:\WINDOWS\system32\cmd.exe /c perl "F:\perl\b.pl"
Argument "4 5 1\n" isn't numeric in numeric comparison (<=>) at F:\perl\b.pl li
e 9, <IN> line 8.
Argument "4 6 3\n" isn't numeric in numeric comparison (<=>) at F:\perl\b.pl li
e 9, <IN> line 8.
Argument "1 9 0\n" isn't numeric in numeric comparison (<=>) at F:\perl\b.pl li
e 9, <IN> line 8.
Argument "1 2 3\n" isn't numeric in numeric comparison (<=>) at F:\perl\b.pl li
e 9, <IN> line 8.
Argument "3 6 2\n" isn't numeric in numeric comparison (<=>) at F:\perl\b.pl li
e 9, <IN> line 8.
Argument "2 0 5\n" isn't numeric in numeric comparison (<=>) at F:\perl\b.pl li
e 9, <IN> line 8.
Argument "2 0 6\n" isn't numeric in numeric comparison (<=>) at F:\perl\b.pl li
e 9, <IN> line 8.
Argument "2 0 8\n" isn't numeric in numeric comparison (<=>) at F:\perl\b.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:\\perl\\dna.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 "@$out\n";
}
结果如下:

C:\WINDOWS\system32\cmd.exe /c perl "F:\perl\b.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...


你可能感兴趣的:(perl :施瓦茨变换,多级排序:首先按照第一列排序,第一列相等的按照第二列排序............)