Two years behind the rest of the class, I needed to solve
a very similar problem. It is in fact not so
computationally complex -- with dynamic programming, it seems it can be solved in O(length(@arr1)). The algorithm below is a bit like edit distance for strings +"edit distance" +"dynamic programming" with scores instead of costs and maxima searched for at any point.
#!/usr/bin/perl -w
use strict;
my @arr1 = qw( 123 a4 b c david e f g 8 h f g 8 X i j k l george );
my @arr2 = qw( c ¤¤ a4 b c d e f g 8 X l m k a4 b c david george );
print "array1: @arr1\n";
print "array2: @arr2\n";
my($longest, $longest_inds) = find_lccs(\@arr1, \@arr2);
print
scalar @$longest_inds,
" instance(s) of subsequence of length $longest, starting at index
+ ",
(join ', ' => @$longest_inds), ":\n";
foreach (@$longest_inds) {
print "@arr1[$_ .. $_ + $longest - 1]\n";
}
sub find_lccs {
my ($arr1, $arr2) = @_;
my %inds;
my $longest = 0;
my @longest_inds = ();
for (my $i = 0; $i < @$arr1; $i++) {
$inds{$arr1->[$i]}->{$i} = 0;
}
for (my $i = $#$arr2; $i >= 0; $i--) {
foreach (keys %{ $inds{$arr2->[$i]} } ) {
if (defined $arr2->[$i+1] && exists $inds{$arr2->[$i+1]}->
+{$_ + 1}) {
$inds{$arr2->[$i]}->{$_} = $inds{$arr2->[$i+1]}->{$_ +
+ 1} + 1;
} else {
$inds{$arr2->[$i]}->{$_} = 1;
}
if ($inds{$arr2->[$i]}->{$_} > $longest ) {
$longest = $inds{$arr2->[$i]}->{$_};
@longest_inds = ($_);
} elsif ($inds{$arr2->[$i]}->{$_} == $longest ) {
push @longest_inds, $_;
}
}
}
@longest_inds = sort {$a <=> $b} @longest_inds;
return ($longest, \@longest_inds);
}
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.
|