利用施瓦茨排序获得范围数据的并集

来源:互联网 发布:mac 粉色口红 编辑:程序博客网 时间:2024/05/22 15:41

有一个文件gi.txt是这样的:

abc     38449   25480-25548 25189-25245

abc     24548   6408-6446

abc     209928  28985-29312 29715-29736

abc     396277  205294-205311 394789-394806

abc     290118  77218-77253 77229-77252 75108-75149 156363-156367

abc     80224   49817-49857 49748-50117 50691-50873

abc     312761  202142-202149 202149-202154 13601-13637

abc     2324    1-2 2-5 8-123 4-6 7-23

abc     22443   9571-9578 9365-9384 8731-8756 9472-9532 8723-8756 9105-9115

abc     2134    8-19 2-7


对于第三列,我们想把有交集的数据范围,合并成一个。比如1-5 3-8 合成的并集为1-8.诸如此类。

perl中,利用施瓦茨排序,然后通过数组前后两个元素的比较,就可以容易的获得想要的结果。

笔者的代码如下:

#! /usr/bin/perl -wuse strict;die "perl $0  gi.txt \n" unless @ARGV==1;my $gi=shift;open IN,$gi||die;while(<IN>){        chomp;        my @a=split/\t/,$_;        my @p=split/\s+/,$a[2];        my @p_sort=map{$_->[0]}                        sort{$a->[1] <=>$b->[1]||$a->[2] <=> $b->[2]}                                map{[$_,split/-/]}@p;        for(my $i=0;$i<$#p_sort;$i++){                my ($b1,$e1)=split/-/,$p_sort[$i];                my ($b2,$e2)=split/-/,$p_sort[$i+1];                if($b2<=$e1 && $e2>=$e1||$b2-$e1==1){                        $p_sort[$i+1]="${b1}-$e2";                        $p_sort[$i]="";                }                if($b2<=$e1 && $e2<$e1){                        $p_sort[$i+1]=$p_sort[$i];                        $p_sort[$i]="";                }        }        my $out;        my @new=grep{!/^$/}@p_sort;        $out.="$_ " for@new;        chop$out;        print "$a[0]\t$a[1]\t$out\n";}close IN;


运行结果如下:


abc     38449   25189-25245 25480-25548

abc     24548   6408-6446

abc     209928  28985-29312 29715-29736

abc     396277  205294-205311 394789-394806

abc     290118  75108-75149 77218-77253 156363-156367

abc     80224   49748-50117 50691-50873

abc     312761  13601-13637 202142-202154

abc     2324    1-123

abc     22443   8723-8756 9105-9115 9365-9384 9472-9532 9571-9578

abc     2134    2-19




0 0
原创粉丝点击