- 论坛徽章:
- 0
|
我一般的方法都是使用两个hash来解决此类问题,供大家参考一下:
定义两个hash:%m 和 %n,核心代码就是$m{$_}++ and $n{$_}++- #!/usr/bin/perl
- use strict;
- use warnings;
- use Data::Dumper;
- my @array1 = split /\n/, <<FILE1;
- 01 02 03 04 05 06
- 02 03 04 05 06 07
- 15 19 22 24 27 28 33 36
- 01 09 14 15 19 23
- FILE1
- my @array2 = split /\n/, <<FILE2;
- 01 02 03 04 05 06
- 02 03 04 05 06 07
- 05 06 07 08 09 10 11
- 03 04 05 06 07 08
- 05 07 09 11 13 14 15
- 08 10 14 15 17 22 23 25
- 11 12 16 18 19 41
- 22 24 29 34 37 39
- FILE2
- my (%m, %n);
- foreach ( @array1, @array2 ) {
- $m{$_}++ and $n{$_}++;
- }
- print Dumper \%m;
- print Dumper \%n;
复制代码 结果如下:- $VAR1 = {
- '03 04 05 06 07 08' => 1,
- '05 07 09 11 13 14 15' => 1,
- '15 19 22 24 27 28 33 36' => 1,
- '05 06 07 08 09 10 11' => 1,
- '11 12 16 18 19 41' => 1,
- '22 24 29 34 37 39' => 1,
- '01 02 03 04 05 06 ' => 2,
- '02 03 04 05 06 07' => 2,
- '08 10 14 15 17 22 23 25' => 1,
- '01 09 14 15 19 23' => 1
- };
- $VAR1 = {
- '01 02 03 04 05 06 ' => 1,
- '02 03 04 05 06 07' => 1
- };
复制代码 分析两个hash的结果值可以逐个推出实际需要的重复还是非重复数据:
1> 求两个数组中的重复项,可以直接是用%n取键值获得,或通过对%m的键值grep- # intersection
- print "\nMethod1:\n";
- print "$_\n" for keys %n;
- print "\nMethod2:\n";
- print "$_\n" for grep { $m{$_} >= 2 } keys %m;
复制代码 结果如下:
Intersection1:
01 02 03 04 05 06
02 03 04 05 06 07
Intersection2:
01 02 03 04 05 06
02 03 04 05 06 07
2> 对两个数组去重,取%m的键值即可- # union
- print "\nUnion:\n";
- print "$_\n" for keys %m;
复制代码 结果如下:
Union:
03 04 05 06 07 08
05 07 09 11 13 14 15
15 19 22 24 27 28 33 36
05 06 07 08 09 10 11
11 12 16 18 19 41
22 24 29 34 37 39
01 02 03 04 05 06
02 03 04 05 06 07
08 10 14 15 17 22 23 25
01 09 14 15 19 23
3> 求两个数组之间不同的项,是用grep对%m的键值操作- # non-uniq
- print "\nNon-uniq:\n";
- print "$_\n" for grep { $m{$_} == 1 } keys %m;
复制代码 结果:
Non-uniq:
03 04 05 06 07 08
05 07 09 11 13 14 15
15 19 22 24 27 28 33 36
05 06 07 08 09 10 11
11 12 16 18 19 41
22 24 29 34 37 39
08 10 14 15 17 22 23 25
01 09 14 15 19 23
使用hash去重是效率很高的方法,但是缺点是无法保持数组中数据原来的顺序。 |
|