仅采用形成连续范围的值

时间:2012-02-27 13:38:43

标签: perl

我有一个包含3列的文件 - >

A1  0   9
A1  4   14
A1  16  24
A1  25  54
A1  64  84
A1  74  84
A2  15  20
A2  19  50

如果col1值相等,我想检查每一行(col2和3中的值)是否已存在或介于前一行的范围之间。 期望的输出是 - >

A1  0   14
A1  16  54
A1  64  84
A2  15  50

我试过了 - >

@ARGV or die "No input file specified";
open $first, '<',$ARGV[0] or die "Unable to open input file: $!";
#open $second,'<', $ARGV[1] or die "Unable to open input file: $!";
$k=0;
while (<$first>) 
{
if($k==0)
{
@cols = split /\s+/;
$p0=$cols[0];
$p1=$cols[1];
$p2=$cols[2];
$p3=$cols[2]+1;
}

else{
@new = split /\s+/;
if ($new[0] eq $p0){
    if ($new[1]>$p3)
        {
    print join("\t", @new),"\n";
    $p0=$new[0];
    $p1=$new[1];
    $p2=$new[2];
    $p3=$new[2]+1;


        }
    elsif ($new[2]>=$p2) 
    {
    print $p0,"\t",$p1,"\t",$new[2],"\n";
    $p2=$new[2];
    $p3=$new[2]+1;
    }

    else 
        {
    $p5=1;

        }   
}

      else 
      {
    print join("\t", @new),"\n";
        $p0=$new[0];
    $p1=$new[1];
    $p2=$new[2];
    $p3=$new[2]+1;

      }}
      $k=1;

}

我得到的输出是 - &gt;

A1    0       14
A1    16      24
A1    16      54
A1    64      84
A1    64      84
A2    15      20
A2    22      50

我无法理解为什么我得到错误的输出。此外,如果有任何方法可以擦除(或覆盖)最后一行,那么这将非常容易。

2 个答案:

答案 0 :(得分:2)

首先,如果你

,帮助你会简单得多
  • 使用strictwarnings,并声明所有变量接近首次使用my
  • 正确缩进代码以显示结构

您的代码失败的原因是您在太多条件下打印数据。例如,当您发现它无法与之前的范围A1 16 24结合时,您输出A1 4 14而不等待后续A1 25 54扩展(当您正确扩展范围并打印它时)再次)。出于同样的原因输出A1 64 84两次:首先是因为它不能与A1 25 54合并,而且因为它已经A1 74 84“扩展”了。最后,A2 15 20会立即输出,因为它有一个新的第一列,即使它与下一行合并并再次输出。

只有当您发现无法再次扩展时,才需要输出范围。这种情况发生在

  • 找到与现有数据不重叠的新记录
  • 到达文件末尾

此代码仅在出现您需要的情况下打印输出。

use strict;
use warnings;

my @data;

while (<DATA>) {

  if (not @data) {
    @data = split;
    next;
  }

  my @new = split;

  if ($new[0] eq $data[0] and $new[1] <= $data[2] + 1) {
    $data[2] = $new[2];
  }
  else {
    print join("\t", @data), "\n";
    @data = @new;
  }

  print join("\t", @data), "\n" if eof DATA;

}

__DATA__
A1  0   9
A1  4   14
A1  16  24
A1  25  54
A1  52  57
A1  59  62
A1  64  84
A1  74  84
A2  15  20
A2  19  50

<强>输出

A1  0 14
A1  16  57
A1  59  62
A1  64  84
A2  15  50

答案 1 :(得分:0)

您需要有一些变量描述当前累积的连续区域。对于每行输入,如果新输入是新的column1标签,或者是相同的标签但不连续,或者是文件结尾,则刷新先前累积的区域。如果它是相同的标签并且是连续的,则更新最小值和最大值。

这假定第1列和第2列已排序。

其余部分留给读者练习。