Levenshtein distance/Alignment: Difference between revisions
m
syntax highlighting fixup automation
m (J -- style changes which help cater to flaws in rosettacode's syntax colorizer) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 22:
{{trans|Nim}}
<
V a = aa.lowercase()
V b = bb.lowercase()
Line 61:
result = levenshteinAlign(‘rosettacode’, ‘raisethysword’)
print(result[0])
print(result[1])</
{{out}}
Line 74:
=={{header|Arturo}}==
<
print join.with:"\n" levenshtein.align "rosettacode" "raisethysword"</
{{out}}
Line 85:
=={{header|C}}==
<
#include <stdlib.h>
#include <string.h>
Line 173:
leven("raisethysword", "rosettacode");
return 0;
}</
{{out}}
<pre>
Line 182:
=={{header|D}}==
Using the standard library.
<
import std.stdio, std.algorithm;
Line 209:
writeln(s1b, "\n", s2b);
}</
{{out}}
<pre>r_oset_tacode
Line 215:
=={{header|Eiffel}}==
<
distance (source, target: STRING): INTEGER
-- Minimum number of operations to turn `source' into `target'.
Line 240:
Result:= l_distance [source.count, target.count]
end
</
Result = 8
Line 250:
{{libheader|biogo}}
Alignment computed by the Needleman-Wunch algorithm, which is used in bioinformatics.
<
import (
Line 305:
}
fmt.Println(string(ma))
}</
{{out}}
The lines after the alignment point out the 8 edits.
Line 316:
=={{header|Haskell}}==
The Wagner–Fischer matrix construction is adopted from [[Levenshtein_distance#Haskell]], however it is reversed in order to simplify it's traversing.
<
costs s1 s2 = reverse $ reverse <$> matrix
where
Line 326:
levenshteinDistance :: String -> String -> Int
levenshteinDistance s1 s2 = head.head $ costs s1 s2</
Line 333:
Instead of indices the Wagner–Fischer matrix and strings are traversed by list truncation, as zippers.
<
alignment s1 s2 = go (costs s1 s2) (reverse s1) (reverse s2) ([],[])
where
Line 350:
nextRow = map tail
nextCol = tail
isEmpty c = null c || null (head c)</
<pre>λ> alignment "palace" "place"
Line 364:
The alternative solution, which extensively produces all minimal alignments for given strings.
<
allAlignments :: String -> String -> [[(Char, Char)]]
allAlignments s1 s2 = go (length s2 - length s1) s1 s2
Line 384:
best = filter ((lev ==) . dist) $ allAlignments s1 s2
lev = levenshteinDistance s1 s2
dist = length . filter (uncurry (/=))</
Line 415:
Translation of java:
<
assert. x <:&# y
D=. x +/&i.&>:&# y
Line 442:
end.
A,:&|.B
)</
Task examples:
<
p-lace
palace
Line 452:
r-oset-tacode
raisethysword
</syntaxhighlight>
=={{header|Java}}==
<
public static String[] alignment(String a, String b) {
Line 494:
System.out.println(result[1]);
}
}</
{{out}}
<pre>
Line 505:
{{trans|Java}}
<
a = lowercase(a)
b = lowercase(b)
Line 547:
foreach(println, levenshteinalign("rosettacode", "raisethysword"))
foreach(println, levenshteinalign("place", "palace"))</
{{out}}
Line 557:
=={{header|Kotlin}}==
{{trans|Java}}
<
fun levenshteinAlign(a: String, b: String): Array<String> {
Line 607:
println(result[0])
println(result[1])
}</
{{out}}
Line 621:
{{incorrect}}
{{works with|Mathematica|7}}
<
{{out}}<pre>8</pre>
Line 627:
=={{header|Nim}}==
{{trans|Kotlin}}
<
proc levenshteinAlign(a, b: string): tuple[a, b: string] =
Line 673:
result = levenshteinAlign("rosettacode","raisethysword")
echo result.a
echo result.b</
{{out}}
Line 683:
=={{header|Perl}}==
<
use warnings;
Line 718:
}
print join "\n", levenshtein_distance_alignment "rosettacode", "raisethysword";</
{{out}}
<pre>ro-settac-o-de
Line 725:
=={{header|Phix}}==
{{trans|Kotlin}} plus the indicator from Go
<!--<
<span style="color: #008080;">function</span> <span style="color: #000000;">LevenshteinAlignment</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">la</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span>
Line 766:
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"rosettacode"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"raisethysword"</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">test</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"place"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"palace"</span><span style="color: #0000FF;">)</span>
<!--</
{{out}}
<pre>
Line 779:
=={{header|Python}}==
<
def levenshtein(str1, str2):
Line 799:
levenshtein("place","palace")
levenshtein("rosettacode","raisethysword")</
{{out}}
<pre>
Line 812:
for a discussion of the code.
<
(define (memoize f)
Line 831:
(min (add1 (levenshtein (rest s) t))
(add1 (levenshtein s (rest t)))
(add1 (levenshtein (rest s) (rest t)))))]))))</
'''Demonstration:'''
<
(string->list "raisethysword"))</
{{out}}
<pre>8</pre>
Line 840:
===Complete version===
Now we extend the code from http://blog.racket-lang.org/2012/08/dynamic-programming-versus-memoization.html to show also the alignment. The code is very similar, but it stores the partial results (number of edits and alignment of each substring) in a lev structure.
<
(struct lev (n s t))
Line 883:
(values (lev-n result)
(list->string (lev-s result))
(list->string (lev-t result)))))</
'''Demonstration:'''
<
(levenshtein "rosettacode" "raisethysword")])
(printf "levenshtein: ~a edits\n" dist)
(displayln exp-s)
(displayln exp-t))</
{{out}}
<pre>levenshtein: 8 edits
Line 898:
(formerly Perl 6)
{{trans|Perl}}
<syntaxhighlight lang="raku"
my @s = flat *, $σ.comb;
my @t = flat *, $t.comb;
Line 922:
}
.say for align 'rosettacode', 'raisethysword';</
{{out}}
<pre>ro-settac-o-de
Line 930:
{{trans|Tcl}}
uses "lcs" from [[Longest common subsequence#Ruby|here]]
<
def levenshtein_align(a, b)
Line 965:
end
puts levenshtein_align("rosettacode", "raisethysword")</
{{out}}
Line 979:
'''src/main.rs'''
<
edit_distance("rosettacode", "raisethysword");</
=={{header|Scala}}==
{{Out}}Best seen running in your browser either by [https://scastie.scala-lang.org/I8BAESkNTjukVPzsWOUyPA ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/I8BAESkNTjukVPzsWOUyPA].
<
import scala.collection.parallel.ParSeq
Line 1,035:
println(alignment._2)
}</
=={{header|Sidef}}==
{{trans|Perl}}
<
s.chars!.prepend!('^')
t.chars!.prepend!('^')
Line 1,071:
}
align("rosettacode", "raisethysword").each { .say }</
{{out}}
ro-settac-o-de
Line 1,078:
=={{header|Tcl}}==
{{tcllib|struct::list}}
<
proc levenshtein/align {a b} {
lassign [struct::list longestCommonSubsequence [split $a ""] [split $b ""]]\
Line 1,113:
}
puts [levenshtein/align "rosettacode" "raisethysword"]</
{{out}}
<pre>
Line 1,123:
{{trans|Kotlin}}
{{libheader|Wren-str}}
<
var levenshteinAlign = Fn.new { |a, b|
Line 1,170:
result = levenshteinAlign.call("rosettacode","raisethysword")
System.print(result[0])
System.print(result[1])</
{{out}}
Line 1,183:
=={{header|zkl}}==
{{trans|Java}}
<
a,b = a.toLower(), b.toLower();
costs := (a.len()+1).pump(List(),'wrap(a){ [1..b.len()].pump(List(a)) });
Line 1,207:
}
return(aPathRev.text.reverse(), bPathRev.text.reverse())
}</
<
println(result[0]);
println(result[1]);</
{{out}}
<pre>
|