2017-02-16 64 views
-2

我想檢查其他範圍的範圍。例如:如何檢查perl範圍內的範圍?

進行檢查:

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

的地方,檢查:

range1: 49-100 
    range2: 800-900 

我想如果存在範圍1或範圍2等檢查在CHECK1每個號碼。如果有任何數字存在,則打印範圍。對於這裏:check1中有50個出現在range1中。 100是check2出現在range1中。但是,檢查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有關,你可以通過_ code code_獲得幫助。 (你也應該解釋數據來自哪裏等) – zdim

+0

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

+0

在你的文本中聽起來像你想檢查check1範圍對所有的range1,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 

編輯: 看來你不喜歡我的答案。這裏是另一個使用奇怪的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