3
4
use vars qw($VERSION @ISA @EXPORT);
10
$y = $x if ($x lt $y);
11
$z = $y if ($y lt $z);
15
16
sub wld { #/* weighted Levenshtein distance */
16
my ($needle, $haystack) = @_;
17
# $dmax is the smallest distance already found, only
18
# smaller distances are computed, otherwise a number
19
# equal or less than the real distance is returned
20
my ($needle, $haystack, $dmax) = @_;
21
$dmax = 98 unless (defined($dmax)); # default when 3rd arg is missing
18
23
my $l1 = length($needle);
19
24
my $l2 = length($haystack);
25
my @s1 = (0, unpack('A' x $l1, $needle));
26
my @s2 = (0, unpack('A' x $l2, $haystack));
27
my $ldiff = abs($l1-$l2);
28
# the distance can not be less than the length difference
29
return $ldiff unless ($ldiff < $dmax);
22
$WMAX=$l1>$l2?$l1:$l2;
31
my $imin; # minimum value of column $i, also lower limit of result
28
for ($j=1; $j<=$WMAX; $j++) {
38
for ($j=1; $j<=$l2; $j++) {
29
39
$dw[0][$j]=$dw[0][$j-1]+$Q;
31
for ($i=1; $i<=$WMAX; $i++) {
41
for ($i=1; $i<=$l1; $i++) {
32
42
$dw[$i][0]=$dw[$i-1][0]+$R;
34
44
for ($i=1; $i<=$l1; $i++) {
35
46
for($j=1; $j<=$l2; $j++) {
36
$dw[$i][$j]=&min3($dw[$i-1][$j-1]+((substr($needle,$i-1,1) eq
37
substr($haystack,$j-1,1))?0:$P),$dw[$i][$j-1]+$Q,$dw[$i-1][$j]+$R);
47
$dw[$i][$j] = &min3( $dw[$i-1][$j-1] + ( ($s1[$i] eq $s2[$j])?0:$P ),
48
$dw[$i][$j-1]+$Q, $dw[$i-1][$j]+$R );
49
$imin = $dw[$i][$j] if ($dw[$i][$j]<$imin);
51
# abort if complete column makes results less than $dmax impossible
52
return ($imin) unless ($imin<$dmax);
40
54
return($dw[$l1][$l2]);