in reply to searching a vector array
If you have your sub-intervals in an array of hashes (minimum and maximum values) sorted in ascending minimum value, you can just work your way through the interval from beginning to end. You can shift off sub-intervals once you have passed their maximum value so save wasted tests. This method will not take up much memory as you are not having to build large vectors, only store minimum and maximum values.
#!/usr/bin/perl # use strict; use warnings; my $intervalStr = q{1..25}; my @subIntervalStrs = qw{ 3..12 7..14 11..19 12..17 }; my ( $begin, $end ) = split m{\.\.}, $intervalStr; my @subIntervals = sort { $a->{ min } <=> $b->{ min } } map { my ( $min, $max ) = split m{\.\.}, $_; { min => $min, max => $max }; } @subIntervalStrs; for my $value ( $begin .. $end ) { my $count = 0; shift @subIntervals while @subIntervals and $value > $subIntervals[ 0 ]->{ max }; for my $subInterval ( @subIntervals ) { if ( $value < $subInterval->{ min } ) { last; } elsif ( $value > $subInterval->{ max } ) { next; } else { $count ++; } } printf qq{%4d => %d\n}, $value, $count; }
The output.
1 => 0 2 => 0 3 => 1 4 => 1 5 => 1 6 => 1 7 => 2 8 => 2 9 => 2 10 => 2 11 => 3 12 => 4 13 => 3 14 => 3 15 => 2 16 => 2 17 => 2 18 => 1 19 => 1 20 => 0 21 => 0 22 => 0 23 => 0 24 => 0 25 => 0
I hope I have understood what you are trying to achieve and that this is helpful.
Update: Corrected a logic error that where the upper end of a sub-interval was not correctly detected.
Cheers,
JohnGG
|
|---|