免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4358 | 回复: 4
打印 上一主题 下一主题

perl区间交集 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-25 15:52 |只看该作者 |倒序浏览
第2列三列没用,那么用每一行的第5列和第6列与下面各列的进行比较,5列为起始坐标,6列为终止坐标。输出他们的最大交集(即如果坐标区间有重叠,则合并之并取其最小的起始坐标和最大的终止坐标)
a.1        1        3        1_b        2        8
a.2        2        5        1_b        5        9
a.3        3        6        1_b        4        7
a.4        2        4        1_b        12        15
c.1        3        8        1_d        1        7
c.2        4        8        1_d        6        8
理想输出
a        1_b        2-9_12-15
c        1_d        1        8
另外还需要输出另一个文件,即最小交集(如果坐标区间有重叠,则合并之并取其最大的起始坐标和最小的终止坐标)
理想结果是
a        1_b        5-7_12-15
c        1_d        6        7
菜鸟,之前大神们写的程序我改不对,恳请大神帮我再写个吧!

论坛徽章:
2
射手座
日期:2014-10-10 15:59:4715-16赛季CBA联赛之上海
日期:2016-03-03 10:27:14
2 [报告]
发表于 2013-12-25 19:51 |只看该作者
回复 1# 清泉一边1
  1. #/usr/bin/env perl

  2. use strict;
  3. use Data::Dumper;

  4. my %h;

  5. while(<DATA>){
  6.     chomp;
  7.     my @a = split;
  8.     my $k = substr($a[0],0,1)."\t".$a[3];
  9.     $h{$k}{min} = $a[4] if $h{$k}{min} > $a[4] or ! defined $h{$k}{min};
  10.     $h{$k}{$a[4]} = $a[5];
  11. }
  12. my %max;
  13. my %min;
  14. my $start;
  15. my $end;
  16. foreach my $k(keys %h){
  17.     foreach my $t (sort{$a<=>$b}grep{/\d/}keys %{$h{$k}}){
  18.         if($t == $h{$k}{min} || $t > $max{$k}{$start}->[-1]){
  19.             $max{$k}{$t} = [$t,$h{$k}{$t}];
  20.             $min{$k}{$t} = [$h{$k}{$t}-$t,$t."-".$h{$k}{$t}];
  21.             $start = $t;
  22.         }elsif($t <= $max{$k}{$start}->[-1] ){  
  23.             $min{$k}{$start} = [$end-$t,$t."-".$end] if $min{$k}{$start}->[0] > ($end-$t);
  24.                         $max{$k}{$start} = [$start,$h{$k}{$t}] if $h{$k}{$t} > $max{$k}{$start}->[-1];
  25.         }
  26.                 $end = $h{$k}{$t};
  27.     }
  28. }

  29. print "Max Gap\n";
  30. foreach my $k (keys %max){
  31.         print $k,"\t";
  32.         print join "_",map{join "-",@{$max{$k}{$_}}}(sort{$a<=>$b}keys %{$max{$k}});
  33.         print "\n";
  34. }
  35. print "Min Gap\n";
  36. foreach my $k (keys %min){
  37.         print $k,"\t";
  38.         print join "_",map{@{$min{$k}{$_}}[1]}(sort{$a<=>$b}keys %{$min{$k}});
  39.         print "\n";
  40. }


  41. __DATA__
  42. a.1        1        3        1_b        2        8
  43. a.2        2        5        1_b        5        9
  44. a.3        3        6        1_b        4        7
  45. a.4        2        4        1_b        12        15
  46. c.1        3        8        1_d        1        7
  47. c.2        4        8        1_d        6        8

  48. -----output-----
  49. Max Gap
  50. a       1_b     2-9_12-15
  51. c       1_d     1-8
  52. Min Gap
  53. a       1_b     5-7_12-15
  54. c       1_d     6-7

复制代码

论坛徽章:
7
戌狗
日期:2013-12-15 20:43:38技术图书徽章
日期:2014-03-05 01:33:12技术图书徽章
日期:2014-03-15 20:31:17未羊
日期:2014-03-25 23:48:20丑牛
日期:2014-04-07 22:37:44巳蛇
日期:2014-04-11 21:58:0915-16赛季CBA联赛之青岛
日期:2016-03-17 20:36:13
3 [报告]
发表于 2013-12-26 00:36 |只看该作者
biru:
  1. #!/usr/bin/perl
  2. my @files = qw/file1 file2/;    # for output

  3. my ( @I, @data, %data ) = ( [ 0, 1 ], [ 2, 3 ] );
  4. while (<DATA>) {
  5.     my ( $A, $B, @C ) = ( /^(\w+)/, (split)[ 3, 4, 5 ] );
  6.     push @data, $A if !@data || ( $data[-1] ne $A );
  7.     push @{ $data{$A}{$B} }, [@C];
  8. }
  9. my @F = map { open my $f, '>', $_; $f } @files;
  10. for my $i (@data) {
  11.     for my $j ( keys %{ $data{$i} } ) {
  12.         my @a = sort { $a->[0] <=> $b->[0] } @{ $data{$i}{$j} };
  13.         my @b = shift @a;
  14.         $_->[0] > $b[-1][1] ? push @b, $_ : push @{$b[-1]}, @$_ for @a;
  15.         @b = map {
  16.           [ ( sort { $a <=> $b } @$_ )[ 0, -1, $#$_ / 2, @$_ / 2 ] ]
  17.         } @b[ @b >= 2 ? ( 0, -1 ) : 0 ];
  18.         my @result = @b > 1
  19.         ? map { @_ = @$_; join '_', map { join '-', @{$_}[@_] } @b } @I
  20.         : map { join "\t", @{ $b[0] }[ @$_ ] } @I;
  21.         print { $F[$_] } "$i\t$j\t$result[$_]\n" for 0 .. 1;
  22.     }
  23. }

  24. __DATA__
  25. a.1        1        3        1_b        2        8
  26. a.2        2        5        1_b        5        9
  27. a.3        3        6        1_b        4        7
  28. a.4        2        4        1_b        12        15
  29. c.1        3        8        1_d        1        7
  30. c.2        4        8        1_d        6        8
复制代码

论坛徽章:
0
4 [报告]
发表于 2013-12-26 15:39 |只看该作者
谢谢!!!回复 3# rubyish


   

论坛徽章:
32
处女座
日期:2013-11-20 23:41:20双子座
日期:2014-06-11 17:20:43戌狗
日期:2014-06-16 11:05:00处女座
日期:2014-07-22 17:30:47狮子座
日期:2014-07-28 15:38:17金牛座
日期:2014-08-05 16:34:01亥猪
日期:2014-08-18 13:34:25白羊座
日期:2014-09-02 15:03:55金牛座
日期:2014-11-10 10:23:58处女座
日期:2014-12-02 09:17:52程序设计版块每日发帖之星
日期:2015-06-16 22:20:002015亚冠之塔什干火车头
日期:2015-06-20 23:28:22
5 [报告]
发表于 2013-12-26 17:31 |只看该作者
我也来一发~
  1. [root@localhost ~]# cat p
  2. #!/usr/bin/perl
  3. use 5.010;

  4. open FILE1, ">a";
  5. open FILE2, ">b";
  6. my %h;

  7. while (<DATA>) {
  8.         @_ = split;
  9.         $_[0] =~ s/\..*//;
  10.         my $t = $_[0]."\t".$_[3];
  11.         push @{ $h{$t} }, [ @_[ 4, 5 ] ];
  12. }

  13. for ( sort keys %h ) {
  14.         my @A = sort { $a->[0] <=> $b->[0] } @{ $h{$_} };
  15.         my @M = shift @A;
  16.         my @N = ( [ $M[0][0], $M[0][1] ] );
  17.         for (@A) {
  18.                 $_->[0] > $M[-1][1] && push @M, $_ and push @N, $_;
  19.                 $_->[1] > $M[-1][1] && ( $M[-1][1] = $_->[1] );
  20.                 $_->[0] > $N[-1][0] && ( $N[-1][0] = $_->[0] );
  21.                 $_->[1] < $N[-1][1] && ( $N[-1][1] = $_->[1] );
  22.         }
  23.         printf FILE1 "%s\t%s\n", $_, join "_", map { join "-", @$_ } @M;
  24.         printf FILE2 "%s\t%s\n", $_, join "_", map { join "-", @$_ } @N;
  25. }

  26. __DATA__
  27. a.1        1        3        1_b        2        8
  28. a.2        2        5        1_b        5        9
  29. a.3        3        6        1_b        4        7
  30. a.4        2        4        1_b        12       15
  31. c.1        3        8        1_d        1        7
  32. c.2        4        8        1_d        6        8
  33. [root@localhost ~]# ./p
  34. [root@localhost ~]# head a b
  35. ==> a <==
  36. a       1_b     2-9_12-15
  37. c       1_d     1-8

  38. ==> b <==
  39. a       1_b     5-7_12-15
  40. c       1_d     6-7
  41. [root@localhost ~]#
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP