in reply to Value in the range struggling (once more)

One of the main issues with your code is the nested while loops. With 1,000 rows in each file, that's 1,000,000 passes through the inner loop. See discussion below, With my solution (below), I've made one pass through the range file to populate a reference hash (%range) and one pass through the code file to check the reference hash (via a subroutine): that's 2,000 passes in total (assuming 1,000 rows in each file).

I see you've checked for the right number of arguments: that's good. You haven't checked whether these are files you can read: less good. Take a look at open: note how I've used lexical (my) variables for the filehandles, the preferred 3-argument form and included some error checking (you can improve the messages).

Here's my code:

#!/usr/bin/env perl use strict; use warnings; if (scalar(@ARGV) != 2) { print "Usage: perl $0 <range.txt> <code.txt>\n"; exit -1; } my %range; open my $fh_range, q{<}, $ARGV[0] or die $!; while (<$fh_range>) { my @range_data = split; push @{$range{$range_data[0]}}, [@range_data[1,2]]; } close $fh_range; open my $fh_code, q{<}, $ARGV[1] or die $!; while (<$fh_code>) { check_range([split]); } close $fh_code; sub check_range { my ($key, $num, $dat) = @{+shift}; if (! exists $range{$key}) { print qq{Key [$key] not found.\n}; return; } for my $range_ref (@{$range{$key}}) { my ($min, $max) = @$range_ref; if ($num >= $min && $num <= $max) { print qq{Key[$key]-Num[$num]-Dat[$dat]}, qq{ in range Min[$min]-Max[$max]\n}; return; } } print qq{Key[$key]-Num[$num]-Dat[$dat] out of bounds.\n}; return; }

Here's the output. Note I've added an extra dummy record to test the out of bounds condition.

$ pm_range_code.pl pm_range.txt pm_code.txt Key[T2]-Num[34]-Dat[lit] in range Min[23]-Max[43] Key [T3] not found. Key[Tn]-Num[100]-Dat[net2] in range Min[66]-Max[124] Key [Tk] not found. Key[T2]-Num[100]-Dat[dummy] out of bounds.

-- Ken

Replies are listed 'Best First'.
Re^2: Value in the range struggling (once more)
by jwkrahn (Abbot) on Mar 16, 2012 at 03:20 UTC
    With 1,000 rows in each file, that's 1,000,000 passes through the inner loop.

    Actually, the inner loop will only execute once because after the filehandle reaches end-of-file it will always return undef.

      ++jwkrahn - most astute :-)

      poegi,

      I didn't look deeply at the mechanics of your code. I made an incorrect assumption with respect to my calculations. Nonetheless, I'm sure you grasp the general principle that nested loops can increase the number of operations exponentially. I'll update my post.

      -- Ken