转载请注明出处:http://bbs.chinaunix.net/thread-4094316-1-1.html
2139765 2139947
2139943 21400642140059 2140216
2140297 2140400
2140393 2140578
2140634 2140821
2140828 2140986
2140967 2141146
2141434 2141616
2141696 2141872
2141864 2141985
2142002 2142175
2142437 2142603
2142912 2143059
2143046 2143220
2143430 2143587
2143587 2143772
现在有这样一组数,可以看到前2行
2139765 2139947
2139943 2140064
中,第一行的第二个数字要比第二行第一个数字要大,即这2个数字区域有重合部分,则输出时要合并输出 2139765 2140064
当然不局限在2行,如果连续三行都有重叠区域,就要一起输出头尾。
反之,如果第一行和第二行没有重叠区域。就原样输出。
解答1:
- use strict;
- use warnings;
- use List::Util qw(max min);
- my $ref = {};
- while (<DATA>) {
- chomp;
- my @arr = split/\s+/;
- push @{$ref->{$.}},$arr[0],$arr[1];
- }
- my $lines = scalar(keys %{$ref});
- my %hash = ();
- my $group = 1;
- push @{$hash{$group}},@{$ref->{1}};
- foreach my $linenum (2..$lines) {
- if ($ref->{$linenum}->[0] <= $ref->{$linenum-1}->[1]) {
- push @{$hash{$group}},@{$ref->{$linenum}};
- }
- else {
- $group++;
- push @{$hash{$group}},@{$ref->{$linenum}};
- }
- }
- foreach my $key (sort {$a<=>$b} keys %hash) {
- my $start = min(@{$hash{$key}});
- my $end = max(@{$hash{$key}});
- print "$start\t$end\n";
- }
- __DATA__
- 2139765 2139947
- 2139943 2140064
- 2140059 2140216
- 2140297 2140400
- 2140393 2140578
- 2140634 2140821
- 2140828 2140986
- 2140967 2141146
- 2141434 2141616
- 2141696 2141872
- 2141864 2141985
- 2142002 2142175
- 2142437 2142603
- 2142912 2143059
- 2143046 2143220
- 2143430 2143587
- 2143587 2143772
if排序的
- #!/usr/bin/perl
- use 5.018;
- my @a = map [split], <DATA>;
- my @b = shift @a;
- for (@a) {
- $_->[0] <= $b[-1][1]
- ? $_->[1] > $b[-1][1] && ( $b[-1][1] = $_->[1] )
- : push @b, $_;
- }
- say join "\t", @$_ for @b;
- __DATA__
- 2139765 2139947
- 2139943 2140064
- 2140059 2140216
- 2140297 2140400
- 2140393 2140578
- 2140634 2140821
- 2140828 2140986
- 2140967 2141146
- 2141434 2141616
- 2141696 2141872
- 2141864 2141985
- 2142002 2142175
- 2142437 2142603
- 2142912 2143059
- 2143046 2143220
- 2143430 2143587
- 2143587 2143772
if不排序的
- #!/usr/bin/perl
- use 5.018;
- my @a = sort { $a->[0] <=> $b->[0] } map [split], <DATA>;
- my @b = shift @a;
- for (@a) {
- $_->[0] <= $b[-1][1]
- ? $_->[1] > $b[-1][1] && ( $b[-1][1] = $_->[1] )
- : push @b, $_;
- }
- say "@$_" for @b;
- __DATA__
- 2139765 2139947
- 2139943 2140064
- 2140059 2140216
- 2140297 2140400
- 2140393 2140578
- 2140634 2140821
- 2140828 2140986
- 2140967 2141146
- 2141434 2141616
- 2141696 2141872
- 2141864 2141985
- 2142002 2142175
- 2142437 2142603
- 2142912 2143059
- 2143046 2143220
- 2143430 2143587
- 2143587 2143772