: # Use perl eval 'exec perl5 -w -S $0 "$@"' if 0; # it is faster to use something like #!/usr/local/bin/perl5 # but this is more portable. ############################################## # String editing distance for hw2 # It expects a file with two words per line, # and it prints their editing distance # ############################################ # # Usage: echo "data dota" | stredit.pl # # will return '1' # ############################################ # my $verbose = 1; my $verbose = 0; my $w1; my $w2; my $idcost = 1; # cost for insertion/deletion of a letter my $subcost = 1; # cost for substitution of non-matching letters while(<>){ chomp($_); @words = split ; # parse the input line - assume it has two words $w1 = $words[0]; $w2 = $words[1]; # print $w1, "\t", $w2, "\n"; my @a1 = split(//, $w1); # turn the string into an array my @a2 = split(//, $w2); my $len1 = scalar ( @a1 ); # find the length of the string my $len2 = scalar ( @a2 ); my $i; my $j; my %cost=(); # hash (=matrix), with cost to fit the prefix 1..i, 1..j for( $i=0; $i <= $len1; $i++ ){ $cost{ $i } { 0 } = $i * $idcost; } for( $j=1; $j <= $len2; $j++ ){ $cost{ 0 } { $j } = $j * $idcost; } for( $i=1; $i<=$len1; $i++ ){ for ( $j = 1; $j <=$len2; $j++){ my $icost = $cost{$i-1}{$j} + $idcost; # insertion my $dcost = $cost{$i}{$j-1} + $idcost; # deletion # substitution my $val1 = ord ( $a1[$i-1] ); my $val2 = ord ( $a2[$j-1] ); my $sc; if ( $val1 == $val2) { $sc = 0;} else{ $sc = $subcost ;} my $scost = $cost{$i-1}{$j-1} + $sc; # now, pick the smallest of the three alternatives $cost{$i}{$j} = min( $icost, $dcost, $scost); } } print "First word=|", $w1, "|", "\t Second word=|", $w2, "|", "\t"; print "EDITING DISTANCE = ", $cost{$len1}{$len2}, "\n"; # just for debugging: if( $verbose ){ for( $i=0; $i<=$len1; $i++ ){ for ( $j = 0; $j <=$len2; $j++){ print $cost{$i}{$j}, "\t"; } print "\n"; } } } # accepts a list of numbers, and returns the minimum sub min{ my @args = @_; my $i=0; my $len = scalar (@args); my $minval; $minval = $args[1]; for($i=0; $i<$len; $i++){ if ($args[$i] < $minval){ $minval = $args[$i]; } } return( $minval); }