数字比较大小并排序问题

转载请注明出处:http://bbs.chinaunix.net/thread-4094316-1-1.html

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

现在有这样一组数,可以看到前2行
2139765        2139947
2139943        2140064
中,第一行的第二个数字要比第二行第一个数字要大,即这2个数字区域有重合部分,则输出时要合并输出 2139765 2140064
当然不局限在2行,如果连续三行都有重叠区域,就要一起输出头尾。
反之,如果第一行和第二行没有重叠区域。就原样输出。


解答1:

  1. use strict;
  2. use warnings;
  3. use List::Util qw(max min);

  4. my $ref = {};
  5. while (<DATA>) {
  6.     chomp;
  7.         my @arr = split/\s+/;
  8.         push @{$ref->{$.}},$arr[0],$arr[1];
  9. }
  10. my $lines = scalar(keys %{$ref});
  11. my %hash = ();
  12. my $group = 1;
  13. push @{$hash{$group}},@{$ref->{1}};
  14. foreach my $linenum (2..$lines) {
  15.     if ($ref->{$linenum}->[0] <= $ref->{$linenum-1}->[1]) {
  16.             push @{$hash{$group}},@{$ref->{$linenum}};
  17.         }
  18.         else {
  19.             $group++;
  20.                 push @{$hash{$group}},@{$ref->{$linenum}};
  21.         }
  22. }
  23. foreach my $key (sort {$a<=>$b} keys %hash) {
  24.     my $start = min(@{$hash{$key}});
  25.         my $end = max(@{$hash{$key}});
  26.         print "$start\t$end\n";
  27. }

  28. __DATA__
  29. 2139765        2139947
  30. 2139943        2140064
  31. 2140059        2140216
  32. 2140297        2140400
  33. 2140393        2140578
  34. 2140634        2140821
  35. 2140828        2140986
  36. 2140967        2141146
  37. 2141434        2141616
  38. 2141696        2141872
  39. 2141864        2141985
  40. 2142002        2142175
  41. 2142437        2142603
  42. 2142912        2143059
  43. 2143046        2143220
  44. 2143430        2143587
  45. 2143587        2143772
解答2:

if排序的

  1. #!/usr/bin/perl
  2. use 5.018;
  3. my @a = map [split], <DATA>;
  4. my @b = shift @a;
  5. for (@a) {
  6.     $_->[0] <= $b[-1][1]
  7.       ? $_->[1] > $b[-1][1] && ( $b[-1][1] = $_->[1] )
  8.       : push @b, $_;
  9. }
  10. say join "\t", @$_ for @b;
  11. __DATA__
  12. 2139765        2139947
  13. 2139943        2140064
  14. 2140059        2140216
  15. 2140297        2140400
  16. 2140393        2140578
  17. 2140634        2140821
  18. 2140828        2140986
  19. 2140967        2141146
  20. 2141434        2141616
  21. 2141696        2141872
  22. 2141864        2141985
  23. 2142002        2142175
  24. 2142437        2142603
  25. 2142912        2143059
  26. 2143046        2143220
  27. 2143430        2143587
  28. 2143587        2143772
解答3:

if不排序的

  1. #!/usr/bin/perl
  2. use 5.018;
  3. my @a = sort { $a->[0] <=> $b->[0] } map [split], <DATA>;
  4. my @b = shift @a;
  5. for (@a) {
  6.     $_->[0] <= $b[-1][1]
  7.       ? $_->[1] > $b[-1][1] && ( $b[-1][1] = $_->[1] )
  8.       : push @b, $_;
  9. }
  10. say "@$_" for @b;


  11. __DATA__
  12. 2139765        2139947
  13. 2139943        2140064
  14. 2140059        2140216
  15. 2140297        2140400
  16. 2140393        2140578
  17. 2140634        2140821
  18. 2140828        2140986
  19. 2140967        2141146
  20. 2141434        2141616
  21. 2141696        2141872
  22. 2141864        2141985
  23. 2142002        2142175
  24. 2142437        2142603
  25. 2142912        2143059
  26. 2143046        2143220
  27. 2143430        2143587
  28. 2143587        2143772

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值