如何防止重复计算?

时间:2013-03-09 17:52:04

标签: perl

我有两组数字范围。

Set 1: 1..6, 2..7, 3..8, 4..9, 5..10
Set 2: 2..7, 2..6

我想将Set 2中的范围与Set 1中的范围进行比较,所以

  1. 计算完美匹配的数量(2..7)

  2. 计算匹配的低位数和不匹配的大写数字(2..6)的实例数

  3. 计算不匹配的低数字和不匹配的大写数字(1..7)的实例数量

  4. 以下代码有效,但它会计算2.3.两次。例如:第2集中的范围2..7符合2.3.的条件。我如何只记录一个实例?

    #!/usr/bin/perl
    use strict;
    use warnings;
    
    #Set 1: 1..6, 2..7, 3..8, 4..9, 5..10
    my @set1_low = (1..5);
    my @set1_up = (6..10);
    my @set1 = ([@set1_low],[@set1_up]);
    
    #Set 2: 2..7, 2..6
    my @set2_low = (2,2);
    my @set2_up = (7,6);
    my @set2 = ([@set2_low],[@set2_up]);
    
    my $size1 = scalar(@set1_low);
    my $size2 = scalar(@set2_low);
    
    my $low_count=0;
    my $up_count=0;
    my $match=0;
    
    for(my $a=0; $a < $size1; $a++){
        my ($lower,$upper) = ($set1[0][$a],$set1[1][$a]);
        for(my $b=0; $b < $size2; $b++){
            #If lower and upper are same to set1, $both++
            if ($lower==$set2[0][$b] && $upper==$set2[1][$b]){
                $match++;
                next;
            }
    
            #If lower match but upper unmatch, $low_count++
            elsif ($lower==$set2[0][$b] && $upper!=$set2[1][$b]){
                $low_count++;
                next;
            }
    
            #if upper match but lower unmatch, $up_count++
            elsif ($lower!=$set2[0][$b] && $upper==$set2[1][$b]){
                $up_count++;
                next;
            } 
         }
     }
     print "Perfect match: $match\n";
     print "lower match, upper unmatch: $low_count\n";
     print "upper match, lower unmatch: $up_count\n";
    

    此外,如果Set 2包含22..32等范围,我如何能够检测到与Set 1中的任何范围不重叠的范围?有什么想法或建议吗?

1 个答案:

答案 0 :(得分:1)

my @set1 = map [ split /\.\./ ], split /\s*,\s*/, '1..6, 2..7, 3..8, 4..9, 5..10';
my @set2 = map [ split /\.\./ ], split /\s*,\s*/, '2..7, 2..6';

my (%exact, %lo, %hi);
for (@set2) {
   my ($l,$h) = @$_;
   ++$exact{$l}{$h};
   ++$lo{$l};
   ++$hi{$h};
}

my $exact               = 0;
my $partial_match_lo_hi = 0;
my $partial_match_lo    = 0;
my $partial_match_hi    = 0;
my %mismatch;
for (@set1) {
   my ($l,$h) = @$_;
   if    ( $exact{$l}{$h}     ) { ++$exact;               }
   elsif ( $lo{$l} && $hi{$h} ) { ++$partial_match_lo_hi; }
   elsif ( $lo{$l}            ) { ++$partial_match_lo;    }
   elsif ( $hi{$h}            ) { ++$partial_match_hi;    }
}