2017-02-16 3 views
-2

Я хочу проверить диапазоны по другим диапазонам. Например:Как проверить диапазон в пределах диапазона включительно в perl?

Чтобы проверить:

check1: 10-50 
    check2: 100-150 
    check3: 500-600 

Место для проверки:

range1: 49-100 
    range2: 800-900 

Я хочу, чтобы проверить каждый номер в Check1 если они присутствуют в range1 или range2 и так далее. Если какое-либо из чисел присутствует, напечатайте диапазон. Для здесь: 50 в check1 присутствует в диапазоне1. 100 - check2 присутствует в диапазоне1. Но проверить 3 нет ни в диапазоне 1, ни в диапазоне2. Как это можно достичь?

Я начал, как это с данными в 4-х колонок:

#!/usr/bin/perl 
use warnings; 
use strict; 
use v5.16; 


my (@check1, @check2, @range1, @range2); 

my $header = <DATA>; 
foreach (<DATA>){ 
    chomp $_; 
    my @columns = split "\t", $_; 



    #check (check1 to check2) in range (all range1 to range2) both inclusive 
    #check 3631 5899 in all range1 to range2, if found print YES 
    #check 3760 5630 in all range1 to range2, if found print YES 

} 

__DATA__ 
#check1 check2 range1 range2 
3631 5899 4706 5095 
3760 5630 5174 5326 
3631 3913 7834 8989 
+2

Пожалуйста, покажите, что вы пытаетесь сделать и почему оно не работает. Это дело с SO, вы можете получить помощь по конкретным проблемам с вашим кодом. (Вы также должны объяснить, откуда поступают данные и т. Д.) – zdim

+0

'my $ range = Set :: IntSpan ('49 -100,800-900 '); if ($ range-> intersect ('10 -50 ')) {...} 'или' my $ range = Set :: IntSpan ([[49,100], [800,900]]); if ($ range-> intersect ([[10,50]])) {...} ' – ysth

+0

в вашем тексте кажется, что вы хотите проверить диапазон check1 на весь диапазон1, range2, range3, но в вашем коде похоже, что вы хотите проверить диапазон check1-check2 на линии с диапазоном range1-range2 на этой линии. Вы можете объяснить? также добавьте, что ваш ожидаемый результат; которые могут быть прояснены. – ysth

ответ

-1

Вот как я бы справиться с этим:

my @checks = (
     [qw(check1 10 50)], 
     [qw(check2 100 150)], 
     [qw(check3 500 600)]); 

while (my $line = <DATA>) { 
    my ($name, $min_r, $max_r) = split (' ', $line); 
    print $name; 
    foreach my $check (@checks) { 
     print " $check->[0]" if overlap($min_r, $max_r, $check->[1], $check->[2]); 
    } 
    print "\n"; 
} 

sub overlap { 
    my ($r1, $r2, $c1, $c2) = @_; 
    return 1 if $r1 >= $c1 && $r1 <= $c2; 
    return 1 if $r2 >= $c1 && $r2 <= $c2; 
    return 1 if $r1 < $c1 && $r2 > $c2; 
    return 0; 
} 

__DATA__ 
range1 49 100 
range2 800 900 

Edit: Это кажется вам не нравится мой ответ. Вот еще одно предложение, использующее странный формат данных из 4 столбцов (я не понимаю, почему у вас будет такое же количество проверок и диапазонов) и отмените роль проверок и диапазонов, как вы сказали в одном из своих ответов. Я печатаю YES, если проверка присутствует в одном из диапазонов. Если вы хотите ДА, если проверка присутствует во всех диапазонах, вам просто нужно добавить 2 отрицания:

my @checks; 
my @ranges; 
my $header = <DATA>; 
while (my $line = <DATA>) { 
    my ($min_c, $max_c, $min_r, $max_r) = split (' ', $line); 
    push @checks, [$min_c, $max_c]; 
    push @ranges, [$min_r, $max_r]; 
} 

foreach my $check (@checks) { 
    print "$check->[0] $check->[1] YES\n" 
     if grep {overlap($check->[0], $check->[1], $_->[0], $_->[1])} @ranges; 
} 

__DATA__ 
#check1 check2 range1 range2 
3631 5899 4706 5095 
3760 5630 5174 5326 
3631 3913 7834 8989 
Смежные вопросы