2013-11-01 2 views
-1

У меня есть два набора диапазонов. Каждый диапазон представляет собой пару целых чисел (начало и конец), представляющих некоторый поддиапазон одного большего диапазона. Мне нужно определить, какие диапазоны от набора A перекрываются, от диапазонов от набора B.Как найти диапазон

+0

не могли понять, как же вывести, что выход. Не могли бы вы немного объяснить? Как вы определяете охват координаты? Я замечаю, что вторая колонка также меняется. Не знаете, как это сделать. – jkshah

+1

Если вы заметили пример, вы найдете 10-12 диапазон в пределах 10-15 и 10-16. Таким образом, существует три перекрытия. Аналогичным образом существует два перекрытия для 10-15 (во второй строке и третьей строке) и только одно перекрытие для 10-16. То, как выводятся числа 3, 2 и 1. У меня очень большой файл со многими перекрытиями. Я должен их сосчитать. Мне нужно использовать perl для этого. Я новичок в perl, я не знаю, как это сделать. – user2923577

+5

@ user2923577 Вы представили способ, способ, waaaaaay слишком мало информации о том, как рассчитать эти числа. Мы не можем читать ваши мысли. Кроме того, это не вопрос о коде Perl, а о том, как решить вашу проблему. Вообще говоря, вы должны представить код Perl и задать вопросы о коде. – TLP

ответ

3

Я думаю, что ваш вход усечен, потому что я не вижу способа получить последние строки вашего ожидаемого выхода.

Но для той части, которая там, я думаю, что вы хотите сценарий, как это:

my %cover; 

foreach my $line (<STDIN>) 
{ 
    chomp $line; 
    my ($tag, $lo, $hi) = split /\s+/, $line; 
    map { $cover{$_}++ } ($lo .. $hi); 
} 


my $beg = 0; 
my $end = 0; 
my $cnt = 0; 

foreach my $val (sort { $a <=> $b } keys %cover) 
{ 
    if ($cover{$val} != $cnt || $val > $end + 1) 
    { 
     if ($cnt > 0) 
     { 
      print "chr1\t$beg\t$end\t$cnt\n"; 
     } 

     $cnt = $cover{$val}; 
     $beg = $val; 
     $end = $val; 
    } else 
    { 
     $end = $val; 
    } 
} 

if ($cnt > 0) 
{ 
    print "chr1\t$beg\t$end\t$cnt\n"; 
} 

Вы не сказали нам, хотя, что делать с chr1 или как связаны его между входом и вывод (есть ли другие значения, которые могут появиться там, например?), поэтому я просто жестко запрограммировал это на выходе. Вам нужно будет соответствующим образом изменить эту часть.

Кроме того, мой скрипт выводит несколько разные диапазоны, чем ваш «ожидаемый результат», в частности, где два диапазона примыкают. Мой сценарий, например, выводит

chr1 556  579  1 
chr1 580  592  2 

но ваш ожидаемый выход дает 580 вместо 579 для первой линии. Я не уверен, что ваш ожидаемый результат правильный. Если вам действительно нужно 580 (что не имеет большого смысла), вы можете изменить сценарий выше, чтобы вывести $end+1, когда $val == $end+1. Это просто странно.

Вот что модифицированная версия кода, который дает странное поведение, когда диапазоны примыкают:

my %cover; 

foreach my $line (<STDIN>) 
{ 
    chomp $line; 
    my ($tag, $lo, $hi) = split /\s+/, $line; 
    map { $cover{$_}++ } ($lo .. $hi); 
} 


my $beg = 0; 
my $end = 0; 
my $cnt = 0; 

foreach my $val (sort { $a <=> $b } keys %cover) 
{ 
    if ($cover{$val} != $cnt || $val > $end + 1) 
    { 
     ## unusual value for '$end' when ranges abut. 
     $end = $val if ($val == $end + 1); 

     if ($cnt > 0) 
     { 
      print "chr1\t$beg\t$end\t$cnt\n"; 
     } 

     $cnt = $cover{$val}; 
     $beg = $val; 
     $end = $val; 
    } else 
    { 
     $end = $val; 
    } 
} 

if ($cnt > 0) 
{ 
    print "chr1\t$beg\t$end\t$cnt\n"; 
} 
+0

Он работал отлично. Огромное спасибо. – user2923577

+0

@ user2923577: Обязательно проголосуйте и примите его, если он решит ваши проблемы. :-) –

Смежные вопросы