2

I have a list of around 5000 words. I want to find the longest prefix match among those words for a given word. For example, in my list I have :

1
121
12234
20345
21345

Now If I search for 12134 the result will be 121 (longest match). I know it can be done in different ways. But, what should be the most efficient way ?

Kamrul Khan
  • 3,260
  • 4
  • 32
  • 59
  • 3
    If you only have 5000 words in your list, I wouldn't worry too much about efficiency. Any reasonable approach will find the match in a tiny fraction of a second. You can find a list of options [here](http://www.perlmonks.org/?node_id=305753). – Mark Reed Aug 03 '15 at 02:12

2 Answers2

3
#!/usr/bin/env perl

use strict;
use warnings;

my @prefixes = qw(
    1
    121
    12234
    20345
    21345
);

my $num = '12134';

my ($longest) = sort { length $b <=> length $a } grep { 0 == index $num, $_ } @prefixes;

print "$longest\n";

Outputs

121
Miller
  • 34,962
  • 4
  • 39
  • 60
1

You can get the regex engine to do this for you. It should be very fast

I hope it's obvious that the regex pattern needs to be built only once, and can then be used to find the longest prefix for any number of target strings

use strict;
use warnings;
use 5.010;

my @prefixes = qw/
    1
    121
    12234
    20345
    21345
/;

my $target = 12134;

my $re = join '|', sort { length $b <=> length $a } @prefixes;
$re = qr/(?:$re)/;

say $1 if $target =~ /^($re)/;

output

121

Update

Alternatively, the Tree::Trie module can be used to implement the trie search that the regex engine provides like this

use strict;
use warnings;
use 5.010;

use Tree::Trie;

my @prefixes = qw/
    1
    121
    12234
    20345
    21345
/;

my $target = 12134;

my $trie = Tree::Trie->new({ deepsearch => 'prefix' });
$trie->add(@prefixes);

say scalar $trie->lookup($target);

The output, of course, is the same as that of the previous code

Borodin
  • 126,100
  • 9
  • 70
  • 144