Jump to content

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)
m (syntax highlighting fixup automation)
Line 22:
{{trans|Nim}}
 
<langsyntaxhighlight lang="11l">F levenshteinAlign(aa, bb)
V a = aa.lowercase()
V b = bb.lowercase()
Line 61:
result = levenshteinAlign(‘rosettacode’, ‘raisethysword’)
print(result[0])
print(result[1])</langsyntaxhighlight>
 
{{out}}
Line 74:
=={{header|Arturo}}==
 
<langsyntaxhighlight lang="rebol">print join.with:"\n" levenshtein.align "place" "palace"
print join.with:"\n" levenshtein.align "rosettacode" "raisethysword"</langsyntaxhighlight>
 
{{out}}
Line 85:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 173:
leven("raisethysword", "rosettacode");
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 182:
=={{header|D}}==
Using the standard library.
<langsyntaxhighlight lang="d">void main() {
import std.stdio, std.algorithm;
 
Line 209:
 
writeln(s1b, "\n", s2b);
}</langsyntaxhighlight>
{{out}}
<pre>r_oset_tacode
Line 215:
 
=={{header|Eiffel}}==
<langsyntaxhighlight lang="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
</langsyntaxhighlight>{{out}}
Result = 8
 
Line 250:
{{libheader|biogo}}
Alignment computed by the Needleman-Wunch algorithm, which is used in bioinformatics.
<langsyntaxhighlight lang="go">package main
 
import (
Line 305:
}
fmt.Println(string(ma))
}</langsyntaxhighlight>
{{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.
<langsyntaxhighlight lang="haskell">costs :: String -> String -> [[Int]]
costs s1 s2 = reverse $ reverse <$> matrix
where
Line 326:
 
levenshteinDistance :: String -> String -> Int
levenshteinDistance s1 s2 = head.head $ costs s1 s2</langsyntaxhighlight>
 
 
Line 333:
Instead of indices the Wagner–Fischer matrix and strings are traversed by list truncation, as zippers.
 
<langsyntaxhighlight lang="haskell">alignment :: String -> String -> (String, String)
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)</langsyntaxhighlight>
 
<pre>λ> alignment "palace" "place"
Line 364:
The alternative solution, which extensively produces all minimal alignments for given strings.
 
<langsyntaxhighlight lang="haskell">-- Produces all possible alignments for two 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 (/=))</langsyntaxhighlight>
 
 
Line 415:
Translation of java:
 
<langsyntaxhighlight Jlang="j">levalign=:4 :0
assert. x <:&# y
D=. x +/&i.&>:&# y
Line 442:
end.
A,:&|.B
)</langsyntaxhighlight>
 
Task examples:
 
<langsyntaxhighlight Jlang="j"> 'place' levalign 'palace'
p-lace
palace
Line 452:
r-oset-tacode
raisethysword
</syntaxhighlight>
</lang>
 
=={{header|Java}}==
<langsyntaxhighlight lang="java">public class LevenshteinAlignment {
 
public static String[] alignment(String a, String b) {
Line 494:
System.out.println(result[1]);
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 505:
{{trans|Java}}
 
<langsyntaxhighlight lang="julia">function levenshteinalign(a::AbstractString, b::AbstractString)
a = lowercase(a)
b = lowercase(b)
Line 547:
 
foreach(println, levenshteinalign("rosettacode", "raisethysword"))
foreach(println, levenshteinalign("place", "palace"))</langsyntaxhighlight>
 
{{out}}
Line 557:
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.1.3
 
fun levenshteinAlign(a: String, b: String): Array<String> {
Line 607:
println(result[0])
println(result[1])
}</langsyntaxhighlight>
 
{{out}}
Line 621:
{{incorrect}}
{{works with|Mathematica|7}}
<langsyntaxhighlight Mathematicalang="mathematica">DamerauLevenshteinDistance["rosettacode", "raisethysword"]</langsyntaxhighlight>
 
{{out}}<pre>8</pre>
Line 627:
=={{header|Nim}}==
{{trans|Kotlin}}
<langsyntaxhighlight Nimlang="nim">import algorithm, sequtils, strutils
 
proc levenshteinAlign(a, b: string): tuple[a, b: string] =
Line 673:
result = levenshteinAlign("rosettacode","raisethysword")
echo result.a
echo result.b</langsyntaxhighlight>
 
{{out}}
Line 683:
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
use warnings;
 
Line 718:
}
print join "\n", levenshtein_distance_alignment "rosettacode", "raisethysword";</langsyntaxhighlight>
{{out}}
<pre>ro-settac-o-de
Line 725:
=={{header|Phix}}==
{{trans|Kotlin}} plus the indicator from Go
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<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>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 779:
 
=={{header|Python}}==
<langsyntaxhighlight Pythonlang="python">from difflib import ndiff
 
def levenshtein(str1, str2):
Line 799:
 
levenshtein("place","palace")
levenshtein("rosettacode","raisethysword")</langsyntaxhighlight>
{{out}}
<pre>
Line 812:
for a discussion of the code.
 
<langsyntaxhighlight lang="racket">#lang racket
 
(define (memoize f)
Line 831:
(min (add1 (levenshtein (rest s) t))
(add1 (levenshtein s (rest t)))
(add1 (levenshtein (rest s) (rest t)))))]))))</langsyntaxhighlight>
'''Demonstration:'''
<langsyntaxhighlight lang="racket">(levenshtein (string->list "rosettacode")
(string->list "raisethysword"))</langsyntaxhighlight>
{{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.
<langsyntaxhighlight Racketlang="racket">#lang racket
 
(struct lev (n s t))
Line 883:
(values (lev-n result)
(list->string (lev-s result))
(list->string (lev-t result)))))</langsyntaxhighlight>
'''Demonstration:'''
<langsyntaxhighlight lang="racket">(let-values ([(dist exp-s exp-t)
(levenshtein "rosettacode" "raisethysword")])
(printf "levenshtein: ~a edits\n" dist)
(displayln exp-s)
(displayln exp-t))</langsyntaxhighlight>
{{out}}
<pre>levenshtein: 8 edits
Line 898:
(formerly Perl 6)
{{trans|Perl}}
<syntaxhighlight lang="raku" perl6line>sub align ( Str $σ, Str $t ) {
my @s = flat *, $σ.comb;
my @t = flat *, $t.comb;
Line 922:
}
.say for align 'rosettacode', 'raisethysword';</langsyntaxhighlight>
{{out}}
<pre>ro-settac-o-de
Line 930:
{{trans|Tcl}}
uses "lcs" from [[Longest common subsequence#Ruby|here]]
<langsyntaxhighlight lang="ruby">require 'lcs'
 
def levenshtein_align(a, b)
Line 965:
end
 
puts levenshtein_align("rosettacode", "raisethysword")</langsyntaxhighlight>
 
{{out}}
Line 979:
 
'''src/main.rs'''
<langsyntaxhighlight Rustlang="rust">extern crate edit_distance;
 
edit_distance("rosettacode", "raisethysword");</langsyntaxhighlight>
 
=={{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].
<langsyntaxhighlight Scalalang="scala">import scala.collection.mutable
import scala.collection.parallel.ParSeq
 
Line 1,035:
println(alignment._2)
 
}</langsyntaxhighlight>
 
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">func align(s, t) {
s.chars!.prepend!('^')
t.chars!.prepend!('^')
Line 1,071:
}
 
align("rosettacode", "raisethysword").each { .say }</langsyntaxhighlight>
{{out}}
ro-settac-o-de
Line 1,078:
=={{header|Tcl}}==
{{tcllib|struct::list}}
<langsyntaxhighlight lang="tcl">package require struct::list
proc levenshtein/align {a b} {
lassign [struct::list longestCommonSubsequence [split $a ""] [split $b ""]]\
Line 1,113:
}
 
puts [levenshtein/align "rosettacode" "raisethysword"]</langsyntaxhighlight>
{{out}}
<pre>
Line 1,123:
{{trans|Kotlin}}
{{libheader|Wren-str}}
<langsyntaxhighlight lang="ecmascript">import "/str" for Str
 
var levenshteinAlign = Fn.new { |a, b|
Line 1,170:
result = levenshteinAlign.call("rosettacode","raisethysword")
System.print(result[0])
System.print(result[1])</langsyntaxhighlight>
 
{{out}}
Line 1,183:
=={{header|zkl}}==
{{trans|Java}}
<langsyntaxhighlight lang="zkl">fcn alignment(a,b){
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())
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">result := alignment("rosettacode", "raisethysword");
println(result[0]);
println(result[1]);</langsyntaxhighlight>
{{out}}
<pre>
10,333

edits

Cookies help us deliver our services. By using our services, you agree to our use of cookies.