Принимая только значения, которые образуют непрерывный диапазон - PullRequest
0 голосов
/ 27 февраля 2012

У меня есть файл с 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

Я хочу проверить, присутствует ли каждая строка (значение в столбцах col2 и 3) или находится в диапазоне диапазона предыдущей строки, если значение col1 равно. Желаемый результат ->

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;

}

и вывод, который я получаю ->

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

Я не могу понять, почему я получаю этот неправильный вывод. Также, если есть какой-либо способ, которым я могу стереть (или перезаписать) последнюю напечатанную строку, тогда это будет очень легко.

Ответы [ 2 ]

2 голосов
/ 27 февраля 2012

Прежде всего, было бы намного проще помочь вам, если бы вы

  • использовали strict и warnings и объявили все свои переменные близкими к первому использованию с 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
0 голосов
/ 27 февраля 2012

Вам нужно иметь некоторые переменные, описывающие текущую накопленную непрерывную область. Для каждой строки ввода очистите ранее накопленную область, если новый вход является новой меткой column1, или такой же меткой, но не является смежной, или является концом файла. Если это та же самая метка и смежные данные, обновите минимальное и максимальное значения.

Предполагается, что столбцы 1 и 2 отсортированы.

Остальное оставлено в качестве упражнения для читателя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...