Levenshtein distance: Difference between revisions

Content added Content deleted
m (→‎{{header|Raku}}: no temp. variable)
(lang -> syntaxhighlight)
Line 31: Line 31:
{{trans|Python}}
{{trans|Python}}


<lang 11l>F minimumEditDistance(=s1, =s2)
<syntaxhighlight lang=11l>F minimumEditDistance(=s1, =s2)
I s1.len > s2.len
I s1.len > s2.len
(s1, s2) = (s2, s1)
(s1, s2) = (s2, s1)
Line 48: Line 48:


print(minimumEditDistance(‘kitten’, ‘sitting’))
print(minimumEditDistance(‘kitten’, ‘sitting’))
print(minimumEditDistance(‘rosettacode’, ‘raisethysword’))</lang>
print(minimumEditDistance(‘rosettacode’, ‘raisethysword’))</syntaxhighlight>


{{out}}
{{out}}
Line 57: Line 57:


=={{header|360 Assembly}}==
=={{header|360 Assembly}}==
<lang 360asm>* Levenshtein distance - 22/04/2020
<syntaxhighlight lang=360asm>* Levenshtein distance - 22/04/2020
LEVENS CSECT
LEVENS CSECT
USING LEVENS,R13 base register
USING LEVENS,R13 base register
Line 229: Line 229:
XDEC DS CL12 temp fo xdeco
XDEC DS CL12 temp fo xdeco
REGEQU
REGEQU
END LEVENS</lang>
END LEVENS</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 241: Line 241:
=={{header|Action!}}==
=={{header|Action!}}==
{{Improve||The output shown does not appear to match the PrintF calls in the code}}
{{Improve||The output shown does not appear to match the PrintF calls in the code}}
<lang action>
<syntaxhighlight lang=action>
DEFINE STRING="CHAR ARRAY" ; sys.act
DEFINE STRING="CHAR ARRAY" ; sys.act
DEFINE width="15" ; max characters 14
DEFINE width="15" ; max characters 14
Line 320: Line 320:
;PrintF("Damerau Levenshtein Distance=%U%E%E",result)
;PrintF("Damerau Levenshtein Distance=%U%E%E",result)
RETURN
RETURN
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>kitten, sitting: 3
<pre>kitten, sitting: 3
Line 327: Line 327:


=={{header|Ada}}==
=={{header|Ada}}==
<lang Ada>with Ada.Text_IO;
<syntaxhighlight lang=Ada>with Ada.Text_IO;


procedure Main is
procedure Main is
Line 360: Line 360:
("rosettacode -> raisethysword:" &
("rosettacode -> raisethysword:" &
Integer'Image (Levenshtein_Distance ("rosettacode", "raisethysword")));
Integer'Image (Levenshtein_Distance ("rosettacode", "raisethysword")));
end Main;</lang>
end Main;</syntaxhighlight>
{{out}}
{{out}}
<pre>kitten -> sitting: 3
<pre>kitten -> sitting: 3
Line 367: Line 367:
=={{header|Aime}}==
=={{header|Aime}}==
{{trans|C}}
{{trans|C}}
<lang aime>integer
<syntaxhighlight lang=aime>integer
dist(data s, t, integer i, j, list d)
dist(data s, t, integer i, j, list d)
{
{
Line 411: Line 411:


0;
0;
}</lang>
}</syntaxhighlight>
{{Out}}
{{Out}}
<pre>`rosettacode' to `raisethysword' is 8
<pre>`rosettacode' to `raisethysword' is 8
Line 421: Line 421:
<br>
<br>
Non-recursive algorithm - although Algol 68 supports recursion, Action! doesn't.
Non-recursive algorithm - although Algol 68 supports recursion, Action! doesn't.
<lang algol68># Calculate Levenshtein distance between strings - translated from the Action! sample #
<syntaxhighlight lang=algol68># Calculate Levenshtein distance between strings - translated from the Action! sample #
BEGIN
BEGIN


Line 470: Line 470:
print((word 1," -> ",word 2,": "));
print((word 1," -> ",word 2,": "));
print(("Levenshtein Distance: ",whole(levenshtein distance(word 1,word 2),0),newline))
print(("Levenshtein Distance: ",whole(levenshtein distance(word 1,word 2),0),newline))
END</lang>
END</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 482: Line 482:
===Iteration===
===Iteration===
Translation of the "fast" C-version
Translation of the "fast" C-version
<lang AppleScript>set dist to findLevenshteinDistance for "sunday" against "saturday"
<syntaxhighlight lang=AppleScript>set dist to findLevenshteinDistance for "sunday" against "saturday"
to findLevenshteinDistance for s1 against s2
to findLevenshteinDistance for s1 against s2
script o
script o
Line 536: Line 536:
end if
end if
end if
end if
end min3</lang>
end min3</syntaxhighlight>


===Composition of generic functions===
===Composition of generic functions===
Line 543: Line 543:


In the ancient tradition of "''Use library functions whenever feasible.''" (for better productivity), and also in the even older functional tradition of composing values (for better reliability) rather than sequencing actions:
In the ancient tradition of "''Use library functions whenever feasible.''" (for better productivity), and also in the even older functional tradition of composing values (for better reliability) rather than sequencing actions:
<lang AppleScript>-- levenshtein :: String -> String -> Int
<syntaxhighlight lang=AppleScript>-- levenshtein :: String -> String -> Int
on levenshtein(sa, sb)
on levenshtein(sa, sb)
set {s1, s2} to {characters of sa, characters of sb}
set {s1, s2} to {characters of sa, characters of sb}
Line 696: Line 696:
map(result, items 1 thru ¬
map(result, items 1 thru ¬
minimum({length of xs, length of ys, length of zs}) of xs)
minimum({length of xs, length of ys, length of zs}) of xs)
end zip3</lang>
end zip3</syntaxhighlight>
{{Out}}
{{Out}}
<lang AppleScript>{3, 3, 8, 8}</lang>
<syntaxhighlight lang=AppleScript>{3, 3, 8, 8}</syntaxhighlight>


=={{header|Arc}}==
=={{header|Arc}}==
Line 704: Line 704:
O(n * m) time, linear space, using lists instead of vectors
O(n * m) time, linear space, using lists instead of vectors


<lang lisp>(def levenshtein (str1 str2)
<syntaxhighlight lang=lisp>(def levenshtein (str1 str2)
(withs l1 len.str1
(withs l1 len.str1
l2 len.str2
l2 len.str2
Line 719: Line 719:
next))
next))
(= row nrev.next)))
(= row nrev.next)))
row.l1))</lang>
row.l1))</syntaxhighlight>


=={{header|Arturo}}==
=={{header|Arturo}}==


<lang rebol>print levenshtein "kitten" "sitting"</lang>
<syntaxhighlight lang=rebol>print levenshtein "kitten" "sitting"</syntaxhighlight>


{{out}}
{{out}}
Line 731: Line 731:
=={{header|AutoHotkey}}==
=={{header|AutoHotkey}}==
{{trans|Go}}
{{trans|Go}}
<lang AutoHotkey>levenshtein(s, t){
<syntaxhighlight lang=AutoHotkey>levenshtein(s, t){
If s =
If s =
return StrLen(t)
return StrLen(t)
Line 749: Line 749:
s1 := "kitten"
s1 := "kitten"
s2 := "sitting"
s2 := "sitting"
MsgBox % "distance between " s1 " and " s2 ": " levenshtein(s1, s2)</lang>It correctly outputs '3'
MsgBox % "distance between " s1 " and " s2 ": " levenshtein(s1, s2)</syntaxhighlight>It correctly outputs '3'


=={{header|AWK}}==
=={{header|AWK}}==
Line 755: Line 755:
Slavishly copied from the very clear AutoHotKey example.
Slavishly copied from the very clear AutoHotKey example.


<lang awk>#!/usr/bin/awk -f
<syntaxhighlight lang=awk>#!/usr/bin/awk -f


BEGIN {
BEGIN {
Line 800: Line 800:
}
}


</syntaxhighlight>
</lang>


Example output:
Example output:
Line 810: Line 810:
Alternative, much faster but also less readable lazy-evaluation version from http://awk.freeshell.org/LevenshteinEditDistance
Alternative, much faster but also less readable lazy-evaluation version from http://awk.freeshell.org/LevenshteinEditDistance
(where the above takes e.g. 0m44.904s in gawk 4.1.3 for 5 edits (length 10 and 14 strings), this takes user 0m0.004s):
(where the above takes e.g. 0m44.904s in gawk 4.1.3 for 5 edits (length 10 and 14 strings), this takes user 0m0.004s):
<lang awk>#!/usr/bin/awk -f
<syntaxhighlight lang=awk>#!/usr/bin/awk -f


function levdist(str1, str2, l1, l2, tog, arr, i, j, a, b, c) {
function levdist(str1, str2, l1, l2, tog, arr, i, j, a, b, c) {
Line 838: Line 838:
return arr[tog, j-1]
return arr[tog, j-1]
}
}
</syntaxhighlight>
</lang>


=={{header|BBC BASIC}}==
=={{header|BBC BASIC}}==
<lang bbcbasic> PRINT "'kitten' -> 'sitting' has distance " ;
<syntaxhighlight lang=bbcbasic> PRINT "'kitten' -> 'sitting' has distance " ;
PRINT ; FNlevenshtein("kitten", "sitting")
PRINT ; FNlevenshtein("kitten", "sitting")
PRINT "'rosettacode' -> 'raisethysword' has distance " ;
PRINT "'rosettacode' -> 'raisethysword' has distance " ;
Line 868: Line 868:
NEXT
NEXT
NEXT j%
NEXT j%
= d%(i%-1,j%-1)</lang>
= d%(i%-1,j%-1)</syntaxhighlight>
'''Output:'''
'''Output:'''
<pre>
<pre>
Line 877: Line 877:
=={{header|BQN}}==
=={{header|BQN}}==
Recursive slow version:
Recursive slow version:
<lang BQN>Levenshtein ← {
<syntaxhighlight lang=BQN>Levenshtein ← {
𝕨 𝕊"": ≠𝕨;
𝕨 𝕊"": ≠𝕨;
""𝕊 𝕩: ≠𝕩;
""𝕊 𝕩: ≠𝕩;
Line 883: Line 883:
Tail←1⊸↓
Tail←1⊸↓
𝕨 =○⊑◶⟨1+·⌊´ 𝕊○Tail ∾ Tail⊸𝕊 ∾ 𝕊⟜Tail, 𝕊○Tail⟩ 𝕩
𝕨 =○⊑◶⟨1+·⌊´ 𝕊○Tail ∾ Tail⊸𝕊 ∾ 𝕊⟜Tail, 𝕊○Tail⟩ 𝕩
}</lang>
}</syntaxhighlight>
Fast version:
Fast version:
<lang BQN>Levenshtein ← @⊸∾⊸{¯1⊑(↕≠𝕨)𝕨{(1⊸+⊸⌊`1⊸+⌊⊑⊸»+𝕨≠𝕗˙)𝕩}´⌽𝕩}</lang>
<syntaxhighlight lang=BQN>Levenshtein ← @⊸∾⊸{¯1⊑(↕≠𝕨)𝕨{(1⊸+⊸⌊`1⊸+⌊⊑⊸»+𝕨≠𝕗˙)𝕩}´⌽𝕩}</syntaxhighlight>
{{out|Example use}}
{{out|Example use}}
<lang> "kitten" Levenshtein "sitting"
<lang> "kitten" Levenshtein "sitting"
Line 892: Line 892:
3
3
"rosettacode" Levenshtein "raisethysword"
"rosettacode" Levenshtein "raisethysword"
8</lang>
8</syntaxhighlight>


=={{header|Bracmat}}==
=={{header|Bracmat}}==
{{trans|C}}
{{trans|C}}
Recursive method, but with memoization.
Recursive method, but with memoization.
<lang bracmat>(levenshtein=
<syntaxhighlight lang=bracmat>(levenshtein=
lev cache
lev cache
. ( lev
. ( lev
Line 921: Line 921:
)
)
& new$hash:?cache
& new$hash:?cache
& lev$!arg);</lang>
& lev$!arg);</syntaxhighlight>
{{out|Demonstrating}}
{{out|Demonstrating}}
<pre> levenshtein$(kitten,sitting)
<pre> levenshtein$(kitten,sitting)
Line 930: Line 930:
=={{header|C}}==
=={{header|C}}==
Recursive method. Deliberately left in an inefficient state to show the recursive nature of the algorithm; notice how it would have become the Wikipedia algorithm if we memoized the function against parameters <code>ls</code> and <code>lt</code>.
Recursive method. Deliberately left in an inefficient state to show the recursive nature of the algorithm; notice how it would have become the Wikipedia algorithm if we memoized the function against parameters <code>ls</code> and <code>lt</code>.
<lang C>#include <stdio.h>
<syntaxhighlight lang=C>#include <stdio.h>
#include <string.h>
#include <string.h>


Line 974: Line 974:


return 0;
return 0;
}</lang>
}</syntaxhighlight>
Take the above and add caching, we get (in [[C99]]):
Take the above and add caching, we get (in [[C99]]):
<lang c>#include <stdio.h>
<syntaxhighlight lang=c>#include <stdio.h>
#include <string.h>
#include <string.h>


Line 1,019: Line 1,019:
return 0;
return 0;
}</lang>
}</syntaxhighlight>


=={{header|C sharp|C#}}==
=={{header|C sharp|C#}}==
This is a straightforward translation of the Wikipedia pseudocode.
This is a straightforward translation of the Wikipedia pseudocode.
<lang csharp>using System;
<syntaxhighlight lang=csharp>using System;


namespace LevenshteinDistance
namespace LevenshteinDistance
Line 1,072: Line 1,072:
}
}
}
}
}</lang>
}</syntaxhighlight>
{{out|Example output}}
{{out|Example output}}
<pre>
<pre>
Line 1,083: Line 1,083:


=={{header|C++}}==
=={{header|C++}}==
<lang c>#include <string>
<syntaxhighlight lang=c>#include <string>
#include <iostream>
#include <iostream>
using namespace std;
using namespace std;
Line 1,137: Line 1,137:


return 0;
return 0;
}</lang>
}</syntaxhighlight>
{{out|Example output}}
{{out|Example output}}
<pre>
<pre>
Line 1,145: Line 1,145:


===Generic ISO C++ version===
===Generic ISO C++ version===
<lang cpp>#include <algorithm>
<syntaxhighlight lang=cpp>#include <algorithm>
#include <iostream>
#include <iostream>
#include <numeric>
#include <numeric>
Line 1,184: Line 1,184:
<< levenshtein_distance(s0, s1) << std::endl;
<< levenshtein_distance(s0, s1) << std::endl;
return 0;
return 0;
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 1,194: Line 1,194:


===Recursive Version===
===Recursive Version===
<lang lisp>(defn levenshtein [str1 str2]
<syntaxhighlight lang=lisp>(defn levenshtein [str1 str2]
(let [len1 (count str1)
(let [len1 (count str1)
len2 (count str2)]
len2 (count str2)]
Line 1,206: Line 1,206:
(levenshtein (rest str1) (rest str2))))))))
(levenshtein (rest str1) (rest str2))))))))


(println (levenshtein "rosettacode" "raisethysword"))</lang>
(println (levenshtein "rosettacode" "raisethysword"))</syntaxhighlight>
{{out}}
{{out}}
<pre>8</pre>
<pre>8</pre>


===Iterative version===
===Iterative version===
<lang lisp>(defn levenshtein [w1 w2]
<syntaxhighlight lang=lisp>(defn levenshtein [w1 w2]
(letfn [(cell-value [same-char? prev-row cur-row col-idx]
(letfn [(cell-value [same-char? prev-row cur-row col-idx]
(min (inc (nth prev-row col-idx))
(min (inc (nth prev-row col-idx))
Line 1,231: Line 1,231:
i))))
i))))
[row-idx] (range 1 (count prev-row)))]
[row-idx] (range 1 (count prev-row)))]
(recur (inc row-idx) max-rows next-prev-row))))))</lang>
(recur (inc row-idx) max-rows next-prev-row))))))</syntaxhighlight>


=={{header|CLU}}==
=={{header|CLU}}==
<lang clu>min = proc [T: type] (a, b: T) returns (T)
<syntaxhighlight lang=clu>min = proc [T: type] (a, b: T) returns (T)
where T has lt: proctype (T,T) returns (bool)
where T has lt: proctype (T,T) returns (bool)
if a<b
if a<b
Line 1,277: Line 1,277:
show("kitten", "sitting")
show("kitten", "sitting")
show("rosettacode", "raisethysword")
show("rosettacode", "raisethysword")
end start_up</lang>
end start_up</syntaxhighlight>
{{out}}
{{out}}
<pre>kitten => sitting: 3
<pre>kitten => sitting: 3
Line 1,284: Line 1,284:
=={{header|COBOL}}==
=={{header|COBOL}}==
GnuCobol 2.2
GnuCobol 2.2
<lang cobol>
<syntaxhighlight lang=cobol>
identification division.
identification division.
program-id. Levenshtein.
program-id. Levenshtein.
Line 1,347: Line 1,347:
display trim(string-a) " -> " trim(string-b) " = " trim(distance)
display trim(string-a) " -> " trim(string-b) " = " trim(distance)
.
.
</syntaxhighlight>
</lang>
{{out|Output}}
{{out|Output}}
<pre>
<pre>
Line 1,356: Line 1,356:


=={{header|CoffeeScript}}==
=={{header|CoffeeScript}}==
<lang coffeescript>levenshtein = (str1, str2) ->
<syntaxhighlight lang=coffeescript>levenshtein = (str1, str2) ->
# more of less ported simple algorithm from JS
# more of less ported simple algorithm from JS
m = str1.length
m = str1.length
Line 1,385: Line 1,385:
console.log levenshtein("stop", "tops")
console.log levenshtein("stop", "tops")
console.log levenshtein("yo", "")
console.log levenshtein("yo", "")
console.log levenshtein("", "yo")</lang>
console.log levenshtein("", "yo")</syntaxhighlight>


=={{header|Common Lisp}}==
=={{header|Common Lisp}}==
<lang lisp>(defun levenshtein (a b)
<syntaxhighlight lang=lisp>(defun levenshtein (a b)
(let* ((la (length a))
(let* ((la (length a))
(lb (length b))
(lb (length b))
Line 1,404: Line 1,404:
(leven la lb))))
(leven la lb))))


(print (levenshtein "rosettacode" "raisethysword"))</lang>
(print (levenshtein "rosettacode" "raisethysword"))</syntaxhighlight>
{{out}}
{{out}}
<pre>8</pre>
<pre>8</pre>
Line 1,410: Line 1,410:
=={{header|Crystal}}==
=={{header|Crystal}}==
The standard library includes [https://crystal-lang.org/api/0.19.2/Levenshtein.html levenshtein] module
The standard library includes [https://crystal-lang.org/api/0.19.2/Levenshtein.html levenshtein] module
<lang ruby>require "levenshtein"
<syntaxhighlight lang=ruby>require "levenshtein"
puts Levenshtein.distance("kitten", "sitting")
puts Levenshtein.distance("kitten", "sitting")
puts Levenshtein.distance("rosettacode", "raisethysword")
puts Levenshtein.distance("rosettacode", "raisethysword")
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>3
<pre>3
Line 1,419: Line 1,419:


{{trans|Ruby 1st version}}
{{trans|Ruby 1st version}}
<lang ruby>module Levenshtein
<syntaxhighlight lang=ruby>module Levenshtein
def self.distance(a, b)
def self.distance(a, b)
Line 1,442: Line 1,442:
Levenshtein.test
Levenshtein.test
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,451: Line 1,451:


{{trans|Ruby 2nd version}}
{{trans|Ruby 2nd version}}
<lang ruby>def levenshtein_distance(str1, str2)
<syntaxhighlight lang=ruby>def levenshtein_distance(str1, str2)
n, m = str1.size, str2.size
n, m = str1.size, str2.size
max = n / 2
max = n / 2
Line 1,482: Line 1,482:
puts "distance(#{a}, #{b}) = #{levenshtein_distance(a, b)}"
puts "distance(#{a}, #{b}) = #{levenshtein_distance(a, b)}"
end
end
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 1,493: Line 1,493:
===Standard Version===
===Standard Version===
The standard library [http://www.digitalmars.com/d/2.0/phobos/std_algorithm.html#levenshteinDistance std.algorithm] module includes a Levenshtein distance function:
The standard library [http://www.digitalmars.com/d/2.0/phobos/std_algorithm.html#levenshteinDistance std.algorithm] module includes a Levenshtein distance function:
<lang d>void main() {
<syntaxhighlight lang=d>void main() {
import std.stdio, std.algorithm;
import std.stdio, std.algorithm;


levenshteinDistance("kitten", "sitting").writeln;
levenshteinDistance("kitten", "sitting").writeln;
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>3</pre>
<pre>3</pre>
Line 1,503: Line 1,503:
===Iterative Version===
===Iterative Version===
{{trans|Java}}
{{trans|Java}}
<lang d>import std.stdio, std.algorithm;
<syntaxhighlight lang=d>import std.stdio, std.algorithm;


int distance(in string s1, in string s2) pure nothrow {
int distance(in string s1, in string s2) pure nothrow {
Line 1,534: Line 1,534:
foreach (p; [["kitten", "sitting"], ["rosettacode", "raisethysword"]])
foreach (p; [["kitten", "sitting"], ["rosettacode", "raisethysword"]])
writefln("distance(%s, %s): %d", p[0], p[1], distance(p[0], p[1]));
writefln("distance(%s, %s): %d", p[0], p[1], distance(p[0], p[1]));
}</lang>
}</syntaxhighlight>


===Memoized Recursive Version===
===Memoized Recursive Version===
{{trans|Python}}
{{trans|Python}}
<lang d>import std.stdio, std.array, std.algorithm, std.functional;
<syntaxhighlight lang=d>import std.stdio, std.array, std.algorithm, std.functional;


uint lDist(T)(in const(T)[] s, in const(T)[] t) nothrow {
uint lDist(T)(in const(T)[] s, in const(T)[] t) nothrow {
Line 1,552: Line 1,552:
lDist("kitten", "sitting").writeln;
lDist("kitten", "sitting").writeln;
lDist("rosettacode", "raisethysword").writeln;
lDist("rosettacode", "raisethysword").writeln;
}</lang>
}</syntaxhighlight>


=={{header|Delphi}}==
=={{header|Delphi}}==
{{Trans|C#}}
{{Trans|C#}}
<lang Delphi>
<syntaxhighlight lang=Delphi>
program Levenshtein_distanceTest;
program Levenshtein_distanceTest;


Line 1,620: Line 1,620:
readln;
readln;
end.
end.
</syntaxhighlight>
</lang>




Line 1,626: Line 1,626:
=={{header|DWScript}}==
=={{header|DWScript}}==
Based on Wikipedia version
Based on Wikipedia version
<lang delphi>function LevenshteinDistance(s, t : String) : Integer;
<syntaxhighlight lang=delphi>function LevenshteinDistance(s, t : String) : Integer;
var
var
i, j : Integer;
i, j : Integer;
Line 1,648: Line 1,648:
end;
end;


PrintLn(LevenshteinDistance('kitten', 'sitting'));</lang>
PrintLn(LevenshteinDistance('kitten', 'sitting'));</syntaxhighlight>


=={{header|Dyalect}}==
=={{header|Dyalect}}==


<lang dyalect>func levenshtein(s, t) {
<syntaxhighlight lang=dyalect>func levenshtein(s, t) {
var n = s.Length()
var n = s.Length()
var m = t.Length()
var m = t.Length()
Line 1,695: Line 1,695:
}
}
run("rosettacode", "raisethysword")</lang>
run("rosettacode", "raisethysword")</syntaxhighlight>


{{out}}
{{out}}
Line 1,702: Line 1,702:


=={{header|EchoLisp}}==
=={{header|EchoLisp}}==
<lang lisp>
<syntaxhighlight lang=lisp>
;; Recursive version adapted from Clojure
;; Recursive version adapted from Clojure
;; Added necessary memoization
;; Added necessary memoization
Line 1,731: Line 1,731:


(levenshtein "rosettacode" "raisethysword") → 8
(levenshtein "rosettacode" "raisethysword") → 8
</syntaxhighlight>
</lang>


=={{header|Ela}}==
=={{header|Ela}}==
This code is translated from Haskell version.
This code is translated from Haskell version.


<lang ela>open list
<syntaxhighlight lang=ela>open list


levenshtein s1 s2 = last <| foldl transform [0 .. length s1] s2
levenshtein s1 s2 = last <| foldl transform [0 .. length s1] s2
where transform (n::ns')@ns c = scanl calc (n+1) <| zip3 s1 ns ns'
where transform (n::ns')@ns c = scanl calc (n+1) <| zip3 s1 ns ns'
where calc z (c', x, y) = minimum [y+1, z+1, x + toInt (c' <> c)]</lang>
where calc z (c', x, y) = minimum [y+1, z+1, x + toInt (c' <> c)]</syntaxhighlight>


Executing:
Executing:


<lang ela>(levenshtein "kitten" "sitting", levenshtein "rosettacode" "raisethysword")</lang>
<syntaxhighlight lang=ela>(levenshtein "kitten" "sitting", levenshtein "rosettacode" "raisethysword")</syntaxhighlight>
{{out}}
{{out}}
<pre>(3, 8)</pre>
<pre>(3, 8)</pre>
Line 1,750: Line 1,750:
=={{header|Elixir}}==
=={{header|Elixir}}==
{{trans|Ruby}}
{{trans|Ruby}}
<lang elixir>defmodule Levenshtein do
<syntaxhighlight lang=elixir>defmodule Levenshtein do
def distance(a, b) do
def distance(a, b) do
ta = String.downcase(a) |> to_charlist |> List.to_tuple
ta = String.downcase(a) |> to_charlist |> List.to_tuple
Line 1,777: Line 1,777:
Enum.each(Enum.chunk(words, 2), fn [a,b] ->
Enum.each(Enum.chunk(words, 2), fn [a,b] ->
IO.puts "distance(#{a}, #{b}) = #{Levenshtein.distance(a,b)}"
IO.puts "distance(#{a}, #{b}) = #{Levenshtein.distance(a,b)}"
end)</lang>
end)</syntaxhighlight>


{{out}}
{{out}}
Line 1,788: Line 1,788:
=={{header|Erlang}}==
=={{header|Erlang}}==
Here are two implementations. The first is the naive version, the second is a memoized version using Erlang's dictionary datatype.
Here are two implementations. The first is the naive version, the second is a memoized version using Erlang's dictionary datatype.
<lang erlang>
<syntaxhighlight lang=erlang>
-module(levenshtein).
-module(levenshtein).
-compile(export_all).
-compile(export_all).
Line 1,824: Line 1,824:
{L,dict:store({S,T},L,C3)}
{L,dict:store({S,T},L,C3)}
end.
end.
</syntaxhighlight>
</lang>
Below is a comparison of the runtimes, measured in microseconds, between the two implementations.
Below is a comparison of the runtimes, measured in microseconds, between the two implementations.
<lang erlang>
<syntaxhighlight lang=erlang>
68> timer:tc(levenshtein,distance,["rosettacode","raisethysword"]).
68> timer:tc(levenshtein,distance,["rosettacode","raisethysword"]).
{774799,8} % {Time, Result}
{774799,8} % {Time, Result}
Line 1,835: Line 1,835:
71> timer:tc(levenshtein,distance_cached,["kitten","sitting"]).
71> timer:tc(levenshtein,distance_cached,["kitten","sitting"]).
{213,3}
{213,3}
</syntaxhighlight>
</lang>


=={{header|ERRE}}==
=={{header|ERRE}}==
<lang ERRE>
<syntaxhighlight lang=ERRE>
PROGRAM LEVENSHTEIN
PROGRAM LEVENSHTEIN


Line 1,882: Line 1,882:
!$ERASE D%
!$ERASE D%
END PROGRAM
END PROGRAM
</syntaxhighlight>
</lang>
{{out}}<pre>
{{out}}<pre>
'kitten' -> 'sitting' has distance 3
'kitten' -> 'sitting' has distance 3
Line 1,890: Line 1,890:
=={{header|Euphoria}}==
=={{header|Euphoria}}==
Code by Jeremy Cowgar from the [http://www.rapideuphoria.com/cgi-bin/asearch.exu?gen=on&keywords=Levenshtein Euphoria File Archive].
Code by Jeremy Cowgar from the [http://www.rapideuphoria.com/cgi-bin/asearch.exu?gen=on&keywords=Levenshtein Euphoria File Archive].
<lang euphoria>function min(sequence s)
<syntaxhighlight lang=euphoria>function min(sequence s)
atom m
atom m
m = s[1]
m = s[1]
Line 1,936: Line 1,936:


? levenshtein("kitten", "sitting")
? levenshtein("kitten", "sitting")
? levenshtein("rosettacode", "raisethysword")</lang>
? levenshtein("rosettacode", "raisethysword")</syntaxhighlight>
{{out}}
{{out}}
<pre>3
<pre>3
Line 1,944: Line 1,944:
=={{header|F_Sharp|F#}}==
=={{header|F_Sharp|F#}}==
=== Standard version ===
=== Standard version ===
<lang FSharp>
<syntaxhighlight lang=FSharp>
open System
open System


Line 1,977: Line 1,977:


Console.ReadKey () |> ignore
Console.ReadKey () |> ignore
</syntaxhighlight>
</lang>


=== Recursive Version ===
=== Recursive Version ===
<lang FSharp>
<syntaxhighlight lang=FSharp>
open System
open System


Line 2,003: Line 2,003:
printfn "dist(kitten, sitting) = %i" (levenshtein "kitten" "sitting")
printfn "dist(kitten, sitting) = %i" (levenshtein "kitten" "sitting")
</syntaxhighlight>
</lang>


=={{header|Factor}}==
=={{header|Factor}}==
<lang factor>USING: lcs prettyprint ;
<syntaxhighlight lang=factor>USING: lcs prettyprint ;
"kitten" "sitting" levenshtein .</lang>
"kitten" "sitting" levenshtein .</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,015: Line 2,015:
=={{header|Forth}}==
=={{header|Forth}}==
{{trans|C}}
{{trans|C}}
<lang forth>: levenshtein ( a1 n1 a2 n2 -- n3)
<syntaxhighlight lang=forth>: levenshtein ( a1 n1 a2 n2 -- n3)
dup \ if either string is empty, difference
dup \ if either string is empty, difference
if \ is inserting all chars from the other
if \ is inserting all chars from the other
Line 2,037: Line 2,037:


s" kitten" s" sitting" levenshtein . cr
s" kitten" s" sitting" levenshtein . cr
s" rosettacode" s" raisethysword" levenshtein . cr</lang>
s" rosettacode" s" raisethysword" levenshtein . cr</syntaxhighlight>


=={{header|Fortran}}==
=={{header|Fortran}}==
<lang Fortran>
<syntaxhighlight lang=Fortran>
program demo_edit_distance
program demo_edit_distance
character(len=:),allocatable :: sources(:),targets(:)
character(len=:),allocatable :: sources(:),targets(:)
Line 2,079: Line 2,079:


end program demo_edit_distance
end program demo_edit_distance
</syntaxhighlight>
</lang>
{{out}}<pre>
{{out}}<pre>
kitten sitting 3 T
kitten sitting 3 T
Line 2,092: Line 2,092:


=={{header|FreeBASIC}}==
=={{header|FreeBASIC}}==
<lang freebasic>' FB 1.05.0 Win64
<syntaxhighlight lang=freebasic>' FB 1.05.0 Win64


' Uses the "iterative with two matrix rows" algorithm
' Uses the "iterative with two matrix rows" algorithm
Line 2,140: Line 2,140:
Print
Print
Print "Press any key to quit"
Print "Press any key to quit"
Sleep</lang>
Sleep</syntaxhighlight>


{{out}}
{{out}}
Line 2,151: Line 2,151:
=={{header|Frink}}==
=={{header|Frink}}==
Frink has a built-in function to calculate the Levenshtein edit distance between two strings:
Frink has a built-in function to calculate the Levenshtein edit distance between two strings:
<lang frink>println[editDistance["kitten","sitting"]]</lang>
<syntaxhighlight lang=frink>println[editDistance["kitten","sitting"]]</syntaxhighlight>
It also has a function to calculate the Levenshtein-Damerau edit distance, <CODE>editDistanceDamerau[<I>str1</I>,<I>str2</I>]</CODE>. This is similar to the <CODE>editDistance</CODE> function but also allows ''swaps'' between two adjoining characters, which count as an edit distance of 1. This may make distances between some strings shorter, by say, treating transposition errors in a word as a less expensive operation than in the pure Levenshtein algorithm, and is generally more useful in more circumstances.
It also has a function to calculate the Levenshtein-Damerau edit distance, <CODE>editDistanceDamerau[<I>str1</I>,<I>str2</I>]</CODE>. This is similar to the <CODE>editDistance</CODE> function but also allows ''swaps'' between two adjoining characters, which count as an edit distance of 1. This may make distances between some strings shorter, by say, treating transposition errors in a word as a less expensive operation than in the pure Levenshtein algorithm, and is generally more useful in more circumstances.


=={{header|FutureBasic}}==
=={{header|FutureBasic}}==
Based on Wikipedia algorithm. Suitable for Pascal strings.
Based on Wikipedia algorithm. Suitable for Pascal strings.
<lang futurebasic>window 1
<syntaxhighlight lang=futurebasic>window 1


local fn LevenshteinDistance( aStr as Str255, bStr as Str255 ) as long
local fn LevenshteinDistance( aStr as Str255, bStr as Str255 ) as long
Line 2,206: Line 2,206:
next
next


HandleEvents</lang>
HandleEvents</syntaxhighlight>


Output:
Output:
Line 2,233: Line 2,233:
=={{header|Go}}==
=={{header|Go}}==
WP algorithm:
WP algorithm:
<lang go>package main
<syntaxhighlight lang=go>package main


import "fmt"
import "fmt"
Line 2,270: Line 2,270:
}
}
return d[len(s)][len(t)]
return d[len(s)][len(t)]
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,276: Line 2,276:
</pre>
</pre>
{{trans|C}}
{{trans|C}}
<lang go>package main
<syntaxhighlight lang=go>package main


import "fmt"
import "fmt"
Line 2,299: Line 2,299:
fmt.Printf("distance between %s and %s: %d\n", s1, s2,
fmt.Printf("distance between %s and %s: %d\n", s1, s2,
levenshtein(s1, s2))
levenshtein(s1, s2))
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,306: Line 2,306:


=={{header|Groovy}}==
=={{header|Groovy}}==
<lang groovy>def distance(String str1, String str2) {
<syntaxhighlight lang=groovy>def distance(String str1, String str2) {
def dist = new int[str1.size() + 1][str2.size() + 1]
def dist = new int[str1.size() + 1][str2.size() + 1]
(0..str1.size()).each { dist[it][0] = it }
(0..str1.size()).each { dist[it][0] = it }
Line 2,324: Line 2,324:
println "Checking distance(${key[0]}, ${key[1]}) == $dist"
println "Checking distance(${key[0]}, ${key[1]}) == $dist"
assert distance(key[0], key[1]) == dist
assert distance(key[0], key[1]) == dist
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 2,335: Line 2,335:


===Implementation 1===
===Implementation 1===
<lang haskell>levenshtein :: Eq a => [a] -> [a] -> Int
<syntaxhighlight lang=haskell>levenshtein :: Eq a => [a] -> [a] -> Int
levenshtein s1 s2 = last $ foldl transform [0 .. length s1] s2
levenshtein s1 s2 = last $ foldl transform [0 .. length s1] s2
where
where
Line 2,343: Line 2,343:


main :: IO ()
main :: IO ()
main = print (levenshtein "kitten" "sitting")</lang>
main = print (levenshtein "kitten" "sitting")</syntaxhighlight>
{{Out}}
{{Out}}
<pre>3</pre>
<pre>3</pre>


===Implementation 2===
===Implementation 2===
<lang haskell>levenshtein :: Eq a => [a] -> [a] -> Int
<syntaxhighlight lang=haskell>levenshtein :: Eq a => [a] -> [a] -> Int
levenshtein s1 [] = length s1
levenshtein s1 [] = length s1
levenshtein [] s2 = length s2
levenshtein [] s2 = length s2
Line 2,359: Line 2,359:


main :: IO ()
main :: IO ()
main = print (levenshtein "kitten" "sitting")</lang>
main = print (levenshtein "kitten" "sitting")</syntaxhighlight>
{{Out}}
{{Out}}
<pre>3</pre>
<pre>3</pre>


=={{header|Icon}} and {{header|Unicon}}==
=={{header|Icon}} and {{header|Unicon}}==
<lang unicon>procedure main()
<syntaxhighlight lang=unicon>procedure main()
every process(!&input)
every process(!&input)
end
end
Line 2,384: Line 2,384:


return d[n,m]-1
return d[n,m]-1
end</lang>
end</syntaxhighlight>
{{out|Example}}
{{out|Example}}
<pre>
<pre>
Line 2,400: Line 2,400:
Io> "rosettacode" levenshtein("raisethysword")
Io> "rosettacode" levenshtein("raisethysword")
==> 8
==> 8
Io> </lang>
Io> </syntaxhighlight>


=={{header|J}}==
=={{header|J}}==
One approach would be a literal transcription of the [[wp:Levenshtein_distance#Computing_Levenshtein_distance|wikipedia implementation]]:
One approach would be a literal transcription of the [[wp:Levenshtein_distance#Computing_Levenshtein_distance|wikipedia implementation]]:
<lang j>levenshtein=:4 :0
<syntaxhighlight lang=j>levenshtein=:4 :0
D=. x +/&i.&>:&# y
D=. x +/&i.&>:&# y
for_i.1+i.#x do.
for_i.1+i.#x do.
Line 2,417: Line 2,417:
end.
end.
{:{:D
{:{:D
)</lang>
)</syntaxhighlight>


First, we setup up an matrix of costs, with 0 or 1 for unexplored cells (1 being where the character pair corresponding to that cell position has two different characters). Note that the "cost to reach the empty string" cells go on the bottom and the right, instead of the top and the left, because this works better with J's "[http://www.jsoftware.com/help/dictionary/d420.htm insert]" operation (which we will call "reduce" in the next paragraph here. It could also be thought of as a right fold which has been constrained such the initial value is the identity value for the operation. Or, just think of it as inserting its operation between each item of its argument...).
First, we setup up an matrix of costs, with 0 or 1 for unexplored cells (1 being where the character pair corresponding to that cell position has two different characters). Note that the "cost to reach the empty string" cells go on the bottom and the right, instead of the top and the left, because this works better with J's "[http://www.jsoftware.com/help/dictionary/d420.htm insert]" operation (which we will call "reduce" in the next paragraph here. It could also be thought of as a right fold which has been constrained such the initial value is the identity value for the operation. Or, just think of it as inserting its operation between each item of its argument...).
Line 2,427: Line 2,427:
We can also do the usual optimization where we only represent one row of the distance matrix at a time:
We can also do the usual optimization where we only represent one row of the distance matrix at a time:


<lang j>levdist =:4 :0
<syntaxhighlight lang=j>levdist =:4 :0
'a b'=. (x;y) /: (#x),(#y)
'a b'=. (x;y) /: (#x),(#y)
D=. >: iz =. i.#b
D=. >: iz =. i.#b
Line 2,434: Line 2,434:
end.
end.
{:D
{:D
)</lang>
)</syntaxhighlight>
{{out|Example use}}
{{out|Example use}}
<lang j> 'kitten' levenshtein 'sitting'
<syntaxhighlight lang=j> 'kitten' levenshtein 'sitting'
3
3
'kitten' levdist 'sitting'
'kitten' levdist 'sitting'
3</lang>
3</syntaxhighlight>
Time and space use:
Time and space use:
<syntaxhighlight lang=j>
<lang j>
timespacex '''kitten'' levenshtein ''sitting'''
timespacex '''kitten'' levenshtein ''sitting'''
0.000113 6016
0.000113 6016
timespacex '''kitten'' levdist ''sitting'''
timespacex '''kitten'' levdist ''sitting'''
1.5e_5 4416</lang>
1.5e_5 4416</syntaxhighlight>
So the levdist implementation is about 7 times faster for this example (which approximately corresponds to the length of the shortest string)
So the levdist implementation is about 7 times faster for this example (which approximately corresponds to the length of the shortest string)
See the [[j:Essays/Levenshtein Distance|Levenshtein distance essay]] on the Jwiki for additional solutions.
See the [[j:Essays/Levenshtein Distance|Levenshtein distance essay]] on the Jwiki for additional solutions.
Line 2,451: Line 2,451:
=={{header|Java}}==
=={{header|Java}}==
Based on the definition for Levenshtein distance given in the Wikipedia article:
Based on the definition for Levenshtein distance given in the Wikipedia article:
<lang java>public class Levenshtein {
<syntaxhighlight lang=java>public class Levenshtein {


public static int distance(String a, String b) {
public static int distance(String a, String b) {
Line 2,478: Line 2,478:
System.out.println("distance(" + data[i] + ", " + data[i+1] + ") = " + distance(data[i], data[i+1]));
System.out.println("distance(" + data[i] + ", " + data[i+1] + ") = " + distance(data[i], data[i+1]));
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>distance(kitten, sitting) = 3
<pre>distance(kitten, sitting) = 3
Line 2,485: Line 2,485:
</pre>
</pre>
{{trans|C}}
{{trans|C}}
<lang java>public class Levenshtein{
<syntaxhighlight lang=java>public class Levenshtein{
public static int levenshtein(String s, String t){
public static int levenshtein(String s, String t){
/* if either string is empty, difference is inserting all chars
/* if either string is empty, difference is inserting all chars
Line 2,530: Line 2,530:
+ levenshtein(sb1.reverse().toString(), sb2.reverse().toString()));
+ levenshtein(sb1.reverse().toString(), sb2.reverse().toString()));
}
}
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>distance between 'kitten' and 'sitting': 3
<pre>distance between 'kitten' and 'sitting': 3
Line 2,538: Line 2,538:
===Iterative space optimized (even bounded) ===
===Iterative space optimized (even bounded) ===
{{trans|Python}}
{{trans|Python}}
<lang java>
<syntaxhighlight lang=java>
import static java.lang.Math.abs;
import static java.lang.Math.abs;
import static java.lang.Math.max;
import static java.lang.Math.max;
Line 2,612: Line 2,612:
}
}
}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 2,622: Line 2,622:
===ES5===
===ES5===
Iterative:
Iterative:
<lang javascript>function levenshtein(a, b) {
<syntaxhighlight lang=javascript>function levenshtein(a, b) {
var t = [], u, i, j, m = a.length, n = b.length;
var t = [], u, i, j, m = a.length, n = b.length;
if (!m) { return n; }
if (!m) { return n; }
Line 2,652: Line 2,652:
console.log('levenstein("' + a + '","' + b + '") was ' + d + ' should be ' + t);
console.log('levenstein("' + a + '","' + b + '") was ' + d + ' should be ' + t);
}
}
});</lang>
});</syntaxhighlight>


===ES6===
===ES6===
Line 2,658: Line 2,658:


By composition of generic functions:
By composition of generic functions:
<lang JavaScript>(() => {
<syntaxhighlight lang=JavaScript>(() => {
'use strict';
'use strict';


Line 2,800: Line 2,800:
// MAIN ---
// MAIN ---
return JSON.stringify(main())
return JSON.stringify(main())
})();</lang>
})();</syntaxhighlight>
{{Out}}
{{Out}}
<pre>[3, 3, 8, 8]</pre>
<pre>[3, 3, 8, 8]</pre>
Line 2,817: Line 2,817:
67ms for rosettacode/raisethysword
67ms for rosettacode/raisethysword
71ms for edocattesor/drowsyhtesiar
71ms for edocattesor/drowsyhtesiar
<syntaxhighlight lang=jq>
<lang jq>
# lookup the distance between s and t in the nested cache,
# lookup the distance between s and t in the nested cache,
# which uses basic properties of the Levenshtein distance to save space:
# which uses basic properties of the Levenshtein distance to save space:
Line 2,868: Line 2,868:


def levenshteinDistance(s;t):
def levenshteinDistance(s;t):
s as $s | t as $t | {} | ld($s;$t) | .[0];</lang>
s as $s | t as $t | {} | ld($s;$t) | .[0];</syntaxhighlight>
'''Task'''
'''Task'''
<lang jq>def demo:
<syntaxhighlight lang=jq>def demo:
"levenshteinDistance between \(.[0]) and \(.[1]) is \( levenshteinDistance(.[0]; .[1]) )";
"levenshteinDistance between \(.[0]) and \(.[1]) is \( levenshteinDistance(.[0]; .[1]) )";
Line 2,877: Line 2,877:
(["edocattesor", "drowsyhtesiar"] | demo),
(["edocattesor", "drowsyhtesiar"] | demo),
(["this_algorithm_is_similar_to",
(["this_algorithm_is_similar_to",
"Damerau-Levenshtein_distance"] | demo)</lang>
"Damerau-Levenshtein_distance"] | demo)</syntaxhighlight>
{{Out}}
{{Out}}
levenshteinDistance between kitten and sitting is 3
levenshteinDistance between kitten and sitting is 3
Line 2,886: Line 2,886:
=={{header|Jsish}}==
=={{header|Jsish}}==
From Javascript, ES5 entry.
From Javascript, ES5 entry.
<lang javascript>/* Levenshtein Distance, in Jsish */
<syntaxhighlight lang=javascript>/* Levenshtein Distance, in Jsish */


function levenshtein(a, b) {
function levenshtein(a, b) {
Line 2,930: Line 2,930:
levenshtein('mississippi', 'swiss miss') ==> 8
levenshtein('mississippi', 'swiss miss') ==> 8
=!EXPECTEND!=
=!EXPECTEND!=
*/</lang>
*/</syntaxhighlight>
{{out}}
{{out}}
<pre>prompt$ jsish -u levenshtein.jsi
<pre>prompt$ jsish -u levenshtein.jsi
Line 2,939: Line 2,939:
'''Recursive''':
'''Recursive''':
{{works with|Julia|1.0}}
{{works with|Julia|1.0}}
<lang julia>function levendist(s::AbstractString, t::AbstractString)
<syntaxhighlight lang=julia>function levendist(s::AbstractString, t::AbstractString)
ls, lt = length.((s, t))
ls, lt = length.((s, t))
ls == 0 && return lt
ls == 0 && return lt
Line 2,950: Line 2,950:


@show levendist("kitten", "sitting") # 3
@show levendist("kitten", "sitting") # 3
@show levendist("rosettacode", "raisethysword") # 8</lang>
@show levendist("rosettacode", "raisethysword") # 8</syntaxhighlight>


'''Iterative''':
'''Iterative''':
{{works with|Julia|0.6}}
{{works with|Julia|0.6}}
<lang julia>function levendist1(s::AbstractString, t::AbstractString)
<syntaxhighlight lang=julia>function levendist1(s::AbstractString, t::AbstractString)
ls, lt = length(s), length(t)
ls, lt = length(s), length(t)
if ls > lt
if ls > lt
Line 2,974: Line 2,974:
end
end
return dist[end]
return dist[end]
end</lang>
end</syntaxhighlight>


Let's see some benchmark:
Let's see some benchmark:
<lang julia>using BenchmarkTools
<syntaxhighlight lang=julia>using BenchmarkTools
println("\n# levendist(kitten, sitting)")
println("\n# levendist(kitten, sitting)")
s, t = "kitten", "sitting"
s, t = "kitten", "sitting"
Line 2,989: Line 2,989:
@btime levendist(s, t)
@btime levendist(s, t)
println(" - Iterative:")
println(" - Iterative:")
@btime levendist1(s, t)</lang>
@btime levendist1(s, t)</syntaxhighlight>


{{out}}
{{out}}
Line 3,007: Line 3,007:
=={{header|Kotlin}}==
=={{header|Kotlin}}==
===Standard Version===
===Standard Version===
<lang scala>// version 1.0.6
<syntaxhighlight lang=scala>// version 1.0.6


// Uses the "iterative with two matrix rows" algorithm referred to in the Wikipedia article.
// Uses the "iterative with two matrix rows" algorithm referred to in the Wikipedia article.
Line 3,039: Line 3,039:
println("'rosettacode' to 'raisethysword' => ${levenshtein("rosettacode", "raisethysword")}")
println("'rosettacode' to 'raisethysword' => ${levenshtein("rosettacode", "raisethysword")}")
println("'sleep' to 'fleeting' => ${levenshtein("sleep", "fleeting")}")
println("'sleep' to 'fleeting' => ${levenshtein("sleep", "fleeting")}")
}</lang>
}</syntaxhighlight>


{{out}}
{{out}}
Line 3,049: Line 3,049:


===Functional/Folding Version===
===Functional/Folding Version===
<lang scala>
<syntaxhighlight lang=scala>
fun levenshtein(s: String, t: String,
fun levenshtein(s: String, t: String,
charScore : (Char, Char) -> Int = { c1, c2 -> if (c1 == c2) 0 else 1}) : Int {
charScore : (Char, Char) -> Int = { c1, c2 -> if (c1 == c2) 0 else 1}) : Int {
Line 3,069: Line 3,069:


}
}
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 3,083: Line 3,083:
Suitable for short strings:
Suitable for short strings:


<lang lisp>
<syntaxhighlight lang=lisp>
(defun levenshtein-simple
(defun levenshtein-simple
(('() str)
(('() str)
Line 3,097: Line 3,097:
(levenshtein-simple str1-tail str2)
(levenshtein-simple str1-tail str2)
(levenshtein-simple str1-tail str2-tail))))))
(levenshtein-simple str1-tail str2-tail))))))
</syntaxhighlight>
</lang>


You can copy and paste that function into an LFE REPL and run it like so:
You can copy and paste that function into an LFE REPL and run it like so:


<lang lisp>
<syntaxhighlight lang=lisp>
> (levenshtein-simple "a" "a")
> (levenshtein-simple "a" "a")
0
0
Line 3,110: Line 3,110:
> (levenshtein-simple "kitten" "sitting")
> (levenshtein-simple "kitten" "sitting")
3
3
</syntaxhighlight>
</lang>


It is not recommended to test strings longer than the last example using this implementation, as performance quickly degrades.
It is not recommended to test strings longer than the last example using this implementation, as performance quickly degrades.
Line 3,116: Line 3,116:
=== Cached Implementation ===
=== Cached Implementation ===


<lang lisp>
<syntaxhighlight lang=lisp>
(defun levenshtein-distance (str1 str2)
(defun levenshtein-distance (str1 str2)
(let (((tuple distance _) (levenshtein-distance
(let (((tuple distance _) (levenshtein-distance
Line 3,143: Line 3,143:
(len (+ 1 (lists:min (list l1 l2 l3)))))
(len (+ 1 (lists:min (list l1 l2 l3)))))
(tuple len (dict:store (tuple str1 str2) len c3)))))))
(tuple len (dict:store (tuple str1 str2) len c3)))))))
</syntaxhighlight>
</lang>


As before, here's some usage in the REPL. Note that longer strings are now possible to compare without incurring long execution times:
As before, here's some usage in the REPL. Note that longer strings are now possible to compare without incurring long execution times:


<lang lisp>
<syntaxhighlight lang=lisp>
> (levenshtein-distance "a" "a")
> (levenshtein-distance "a" "a")
0
0
Line 3,158: Line 3,158:
> (levenshtein-distance "rosettacode" "raisethysword")
> (levenshtein-distance "rosettacode" "raisethysword")
8
8
</syntaxhighlight>
</lang>


=={{header|Liberty BASIC}}==
=={{header|Liberty BASIC}}==
<lang lb>'Levenshtein Distance translated by Brandon Parker
<syntaxhighlight lang=lb>'Levenshtein Distance translated by Brandon Parker
'08/19/10
'08/19/10
'from http://www.merriampark.com/ld.htm#VB
'from http://www.merriampark.com/ld.htm#VB
Line 3,206: Line 3,206:
Next i
Next i
LevenshteinDistance = d(n, m)
LevenshteinDistance = d(n, m)
End Function </lang>
End Function </syntaxhighlight>


=={{header|Limbo}}==
=={{header|Limbo}}==
{{trans|Go}}
{{trans|Go}}
<lang limbo>implement Levenshtein;
<syntaxhighlight lang=limbo>implement Levenshtein;


include "sys.m"; sys: Sys;
include "sys.m"; sys: Sys;
Line 3,257: Line 3,257:
return a + 1;
return a + 1;
}
}
</syntaxhighlight>
</lang>


{{output}}
{{output}}
Line 3,268: Line 3,268:
=={{header|LiveCode}}==
=={{header|LiveCode}}==
{{trans|Go}}
{{trans|Go}}
<lang LiveCode>
<syntaxhighlight lang=LiveCode>
//Code By Neurox66
//Code By Neurox66
function Levenshtein pString1 pString2
function Levenshtein pString1 pString2
Line 3,292: Line 3,292:
put Levenshtein("kitten","sitting")
put Levenshtein("kitten","sitting")
put Levenshtein("rosettacode","raisethysword")
put Levenshtein("rosettacode","raisethysword")
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>3
<pre>3
Line 3,299: Line 3,299:
=={{header|Lobster}}==
=={{header|Lobster}}==
{{trans|C}}
{{trans|C}}
<lang Lobster>def levenshtein(s: string, t: string) -> int:
<syntaxhighlight lang=Lobster>def levenshtein(s: string, t: string) -> int:


def makeNxM(n: int, m: int, v: int) -> [[int]]:
def makeNxM(n: int, m: int, v: int) -> [[int]]:
Line 3,334: Line 3,334:


assert 3 == levenshtein("kitten", "sitting")
assert 3 == levenshtein("kitten", "sitting")
assert 8 == levenshtein("rosettacode", "raisethysword")</lang>
assert 8 == levenshtein("rosettacode", "raisethysword")</syntaxhighlight>


=={{header|Lua}}==
=={{header|Lua}}==
<lang lua>function leven(s,t)
<syntaxhighlight lang=lua>function leven(s,t)
if s == '' then return t:len() end
if s == '' then return t:len() end
if t == '' then return s:len() end
if t == '' then return s:len() end
Line 3,356: Line 3,356:


print(leven("kitten", "sitting"))
print(leven("kitten", "sitting"))
print(leven("rosettacode", "raisethysword"))</lang>
print(leven("rosettacode", "raisethysword"))</syntaxhighlight>
{{out}}
{{out}}
<pre>3
<pre>3
Line 3,362: Line 3,362:


=={{header|M2000 Interpreter}}==
=={{header|M2000 Interpreter}}==
<lang M2000 Interpreter>
<syntaxhighlight lang=M2000 Interpreter>
Module Checkit {
Module Checkit {
\\ Iterative with two matrix rows
\\ Iterative with two matrix rows
Line 3,429: Line 3,429:
}
}
Checkit2
Checkit2
</syntaxhighlight>
</lang>


=={{header|Maple}}==
=={{header|Maple}}==
<lang Maple>
<syntaxhighlight lang=Maple>
> with(StringTools):
> with(StringTools):
> Levenshtein("kitten","sitting");
> Levenshtein("kitten","sitting");
Line 3,439: Line 3,439:
> Levenshtein("rosettacode","raisethysword");
> Levenshtein("rosettacode","raisethysword");
8
8
</syntaxhighlight>
</lang>


=={{header|Mathematica}}/{{header|Wolfram Language}}==
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<lang Mathematica>EditDistance["kitten","sitting"]
<syntaxhighlight lang=Mathematica>EditDistance["kitten","sitting"]
EditDistance["rosettacode","raisethysword"]</lang>
EditDistance["rosettacode","raisethysword"]</syntaxhighlight>
{{out}}
{{out}}
<pre>3
<pre>3
Line 3,449: Line 3,449:


=={{header|MATLAB}}==
=={{header|MATLAB}}==
<lang MATLAB>
<syntaxhighlight lang=MATLAB>
function score = levenshtein(s1, s2)
function score = levenshtein(s1, s2)
% score = levenshtein(s1, s2)
% score = levenshtein(s1, s2)
Line 3,480: Line 3,480:
score = current_row(end);
score = current_row(end);
end
end
</syntaxhighlight>
</lang>
Source : [https://github.com/benhamner/Metrics/blob/master/MATLAB/metrics/levenshtein.m]
Source : [https://github.com/benhamner/Metrics/blob/master/MATLAB/metrics/levenshtein.m]


=={{header|MiniScript}}==
=={{header|MiniScript}}==
In the Mini Micro environment, this function is part of the stringUtil library module, and can be used like so:
In the Mini Micro environment, this function is part of the stringUtil library module, and can be used like so:
<lang MiniScript>import "stringUtil"
<syntaxhighlight lang=MiniScript>import "stringUtil"
print "kitten".editDistance("sitting")</lang>
print "kitten".editDistance("sitting")</syntaxhighlight>


In environments where the stringUtil module is not available, you'd have to define it yourself:
In environments where the stringUtil module is not available, you'd have to define it yourself:
<lang MiniScript>string.editDistance = function(s2)
<syntaxhighlight lang=MiniScript>string.editDistance = function(s2)
n = self.len
n = self.len
m = s2.len
m = s2.len
Line 3,528: Line 3,528:
end function
end function


print "kitten".editDistance("sitting")</lang>
print "kitten".editDistance("sitting")</syntaxhighlight>


'''Output:'''
'''Output:'''
Line 3,536: Line 3,536:


=={{header|Modula-2}}==
=={{header|Modula-2}}==
<lang modula2>MODULE LevenshteinDistance;
<syntaxhighlight lang=modula2>MODULE LevenshteinDistance;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
FROM Strings IMPORT Length;
FROM Strings IMPORT Length;
Line 3,588: Line 3,588:
ShowDistance("kitten", "sitting");
ShowDistance("kitten", "sitting");
ShowDistance("rosettacode", "raisethysword");
ShowDistance("rosettacode", "raisethysword");
END LevenshteinDistance.</lang>
END LevenshteinDistance.</syntaxhighlight>
{{out}}
{{out}}
<pre>kitten -> sitting: 3
<pre>kitten -> sitting: 3
Line 3,595: Line 3,595:
=={{header|NetRexx}}==
=={{header|NetRexx}}==
{{trans|ooRexx}}
{{trans|ooRexx}}
<lang NetRexx>/* NetRexx */
<syntaxhighlight lang=NetRexx>/* NetRexx */
options replace format comments java crossref symbols nobinary
options replace format comments java crossref symbols nobinary


Line 3,647: Line 3,647:


return d[m + 1, n + 1]
return d[m + 1, n + 1]
</syntaxhighlight>
</lang>
'''Output:'''
'''Output:'''
<pre>
<pre>
Line 3,656: Line 3,656:
=={{header|Nim}}==
=={{header|Nim}}==
Nim provides a function in module "std/editdistance" to compute the Levenshtein distance between two strings containing ASCII characters only or containing UTF-8 encoded Unicode runes.
Nim provides a function in module "std/editdistance" to compute the Levenshtein distance between two strings containing ASCII characters only or containing UTF-8 encoded Unicode runes.
<lang nim>import std/editdistance
<syntaxhighlight lang=nim>import std/editdistance


echo editDistanceAscii("kitten", "sitting")
echo editDistanceAscii("kitten", "sitting")
echo editDistanceAscii("rosettacode", "raisethysword")</lang>
echo editDistanceAscii("rosettacode", "raisethysword")</syntaxhighlight>


{{out}}
{{out}}
Line 3,667: Line 3,667:
{{trans|Python}}
{{trans|Python}}
Here is a translation of the Python version.
Here is a translation of the Python version.
<lang nim>import sequtils
<syntaxhighlight lang=nim>import sequtils


func min(a, b, c: int): int {.inline.} = min(a, min(b, c))
func min(a, b, c: int): int {.inline.} = min(a, min(b, c))
Line 3,691: Line 3,691:


echo levenshteinDistance("kitten","sitting")
echo levenshteinDistance("kitten","sitting")
echo levenshteinDistance("rosettacode","raisethysword")</lang>
echo levenshteinDistance("rosettacode","raisethysword")</syntaxhighlight>


=={{header|Objeck}}==
=={{header|Objeck}}==
{{trans|C#}}
{{trans|C#}}
<lang objeck>class Levenshtein {
<syntaxhighlight lang=objeck>class Levenshtein {
function : Main(args : String[]) ~ Nil {
function : Main(args : String[]) ~ Nil {
if(args->Size() = 2) {
if(args->Size() = 2) {
Line 3,728: Line 3,728:
return d[s->Size(), t->Size()];
return d[s->Size(), t->Size()];
}
}
}</lang>
}</syntaxhighlight>


=={{header|Objective-C}}==
=={{header|Objective-C}}==
Translation of the C# code into a NSString category
Translation of the C# code into a NSString category
<lang objc>@interface NSString (levenshteinDistance)
<syntaxhighlight lang=objc>@interface NSString (levenshteinDistance)
- (NSUInteger)levenshteinDistanceToString:(NSString *)string;
- (NSUInteger)levenshteinDistanceToString:(NSString *)string;
@end
@end
Line 3,766: Line 3,766:
return r;
return r;
}
}
@end</lang>
@end</syntaxhighlight>


=={{header|OCaml}}==
=={{header|OCaml}}==
Translation of the pseudo-code of the Wikipedia article:
Translation of the pseudo-code of the Wikipedia article:
<lang ocaml>let minimum a b c =
<syntaxhighlight lang=ocaml>let minimum a b c =
min a (min b c)
min a (min b c)


Line 3,810: Line 3,810:
test "kitten" "sitting";
test "kitten" "sitting";
test "rosettacode" "raisethysword";
test "rosettacode" "raisethysword";
;;</lang>
;;</syntaxhighlight>
=== A recursive functional version ===
=== A recursive functional version ===
This could be made faster with memoization
This could be made faster with memoization
<lang OCaml>let levenshtein s t =
<syntaxhighlight lang=OCaml>let levenshtein s t =
let rec dist i j = match (i,j) with
let rec dist i j = match (i,j) with
| (i,0) -> i
| (i,0) -> i
Line 3,829: Line 3,829:
let () =
let () =
test "kitten" "sitting";
test "kitten" "sitting";
test "rosettacode" "raisethysword";</lang>
test "rosettacode" "raisethysword";</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,837: Line 3,837:


=={{header|ooRexx}}==
=={{header|ooRexx}}==
<lang ooRexx>
<syntaxhighlight lang=ooRexx>
say "kitten -> sitting:" levenshteinDistance("kitten", "sitting")
say "kitten -> sitting:" levenshteinDistance("kitten", "sitting")
say "rosettacode -> raisethysword:" levenshteinDistance("rosettacode", "raisethysword")
say "rosettacode -> raisethysword:" levenshteinDistance("rosettacode", "raisethysword")
Line 3,884: Line 3,884:


return d[m + 1, n + 1 ]
return d[m + 1, n + 1 ]
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 3,894: Line 3,894:
{{trans|JavaScript}}
{{trans|JavaScript}}
{{Works with|PARI/GP|2.7.4 and above}}
{{Works with|PARI/GP|2.7.4 and above}}
<lang parigp>
<syntaxhighlight lang=parigp>
\\ Levenshtein distance between two words
\\ Levenshtein distance between two words
\\ 6/21/16 aev
\\ 6/21/16 aev
Line 3,918: Line 3,918:
levensDist("X","oX");
levensDist("X","oX");
}
}
</lang>
</syntaxhighlight>
{{Output}}
{{Output}}
Line 3,932: Line 3,932:
=={{header|Pascal}}==
=={{header|Pascal}}==
A fairly direct translation of the wikipedia pseudo code:
A fairly direct translation of the wikipedia pseudo code:
<lang pascal>Program LevenshteinDistanceDemo(output);
<syntaxhighlight lang=pascal>Program LevenshteinDistanceDemo(output);


uses
uses
Line 3,969: Line 3,969:
s2 := 'raisethysword';
s2 := 'raisethysword';
writeln('The Levenshtein distance between "', s1, '" and "', s2, '" is: ', LevenshteinDistance(s1, s2));
writeln('The Levenshtein distance between "', s1, '" and "', s2, '" is: ', LevenshteinDistance(s1, s2));
end.</lang>
end.</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 3,978: Line 3,978:
=={{header|Perl}}==
=={{header|Perl}}==
Recursive algorithm, as in the C sample. You are invited to comment out the line where it says so, and see the speed difference. By the way, there's the <code>Memoize</code> standard module, but it requires setting quite a few parameters to work right for this example, so I'm just showing the simple minded caching scheme here.
Recursive algorithm, as in the C sample. You are invited to comment out the line where it says so, and see the speed difference. By the way, there's the <code>Memoize</code> standard module, but it requires setting quite a few parameters to work right for this example, so I'm just showing the simple minded caching scheme here.
<lang Perl>use List::Util qw(min);
<syntaxhighlight lang=Perl>use List::Util qw(min);


my %cache;
my %cache;
Line 4,002: Line 4,002:
}
}


print leven('rosettacode', 'raisethysword'), "\n";</lang>
print leven('rosettacode', 'raisethysword'), "\n";</syntaxhighlight>


Iterative solution:
Iterative solution:


<lang perl>use List::Util qw(min);
<syntaxhighlight lang=perl>use List::Util qw(min);


sub leven {
sub leven {
Line 4,028: Line 4,028:
}
}


print leven('rosettacode', 'raisethysword'), "\n";</lang>
print leven('rosettacode', 'raisethysword'), "\n";</syntaxhighlight>


=={{header|Phix}}==
=={{header|Phix}}==
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 4,072: Line 4,072:
<span style="color: #0000FF;">{</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}}</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}}</span>
<span style="color: #7060A8;">papply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #000000;">test</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">papply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">false</span><span style="color: #0000FF;">,</span><span style="color: #000000;">test</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 4,086: Line 4,086:
=== alternative ===
=== alternative ===
Modelled after the Processing code, uses a single/smaller array, passes the same tests as above.
Modelled after the Processing code, uses a single/smaller array, passes the same tests as above.
<!--<lang Phix>(phixonline)-->
<!--<syntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #008080;">function</span> <span style="color: #000000;">levenshtein</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: #008080;">function</span> <span style="color: #000000;">levenshtein</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;">sequence</span> <span style="color: #000000;">costs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">costs</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
Line 4,101: Line 4,101:
<span style="color: #008080;">return</span> <span style="color: #000000;">costs</span><span style="color: #0000FF;">[$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">costs</span><span style="color: #0000FF;">[$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<!--</lang>-->
<!--</syntaxhighlight>-->


=={{header|PHP}}==
=={{header|PHP}}==
<lang PHP>
<syntaxhighlight lang=PHP>
echo levenshtein('kitten','sitting');
echo levenshtein('kitten','sitting');
echo levenshtein('rosettacode', 'raisethysword');
echo levenshtein('rosettacode', 'raisethysword');
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 4,116: Line 4,116:
==Iterative==
==Iterative==
Based on the iterative algorithm at Wikipedia. Picat is 1-based so some adjustments are needed.
Based on the iterative algorithm at Wikipedia. Picat is 1-based so some adjustments are needed.
<lang Picat>levenshtein(S,T) = Dist =>
<syntaxhighlight lang=Picat>levenshtein(S,T) = Dist =>
M = 1+S.length,
M = 1+S.length,
N = 1+T.length,
N = 1+T.length,
Line 4,141: Line 4,141:
end,
end,


Dist = D[M,N].</lang>
Dist = D[M,N].</syntaxhighlight>


===Tabled recursive version===
===Tabled recursive version===
<lang Picat>table
<syntaxhighlight lang=Picat>table
levenshtein_rec(S,T) = Dist =>
levenshtein_rec(S,T) = Dist =>
Dist1 = 0,
Dist1 = 0,
Line 4,161: Line 4,161:
Dist1 := A + 1
Dist1 := A + 1
end,
end,
Dist = Dist1.</lang>
Dist = Dist1.</syntaxhighlight>


===Mode-directed tabling===
===Mode-directed tabling===
{{trans|Prolog}}
{{trans|Prolog}}
<lang Picat>
<syntaxhighlight lang=Picat>
levenshtein_mode(S,T) = Dist =>
levenshtein_mode(S,T) = Dist =>
lev(S, T, Dist).
lev(S, T, Dist).
Line 4,174: Line 4,174:
lev([_|L], [_|R], D) :- lev(L, R, H), D is H+1.
lev([_|L], [_|R], D) :- lev(L, R, H), D is H+1.
lev([_|L], R, D) :- lev(L, R, H), D is H+1.
lev([_|L], R, D) :- lev(L, R, H), D is H+1.
lev(L, [_|R], D) :- lev(L, R, H), D is H+1.</lang>
lev(L, [_|R], D) :- lev(L, R, H), D is H+1.</syntaxhighlight>




===Test===
===Test===
<lang Picat>go =>
<syntaxhighlight lang=Picat>go =>
S = [
S = [
Line 4,196: Line 4,196:
nl
nl
end,
end,
nl.</lang>
nl.</syntaxhighlight>


{{out}}
{{out}}
Line 4,227: Line 4,227:
===Benchmark on larger strings===
===Benchmark on larger strings===
Benchmarking the methods with larger strings of random lengths (between 1 and 2000).
Benchmarking the methods with larger strings of random lengths (between 1 and 2000).
<lang Picat>go2 =>
<syntaxhighlight lang=Picat>go2 =>
_ = random2(),
_ = random2(),
Len = 2000,
Len = 2000,
Line 4,250: Line 4,250:
Alpha = "abcdefghijklmnopqrstuvxyz",
Alpha = "abcdefghijklmnopqrstuvxyz",
Len = Alpha.length,
Len = Alpha.length,
S := [Alpha[random(1,Len)] : _ in 1..random(1,MaxLen)].</lang>
S := [Alpha[random(1,Len)] : _ in 1..random(1,MaxLen)].</syntaxhighlight>


Here is sample run. The version using mode-directed tabling is clearly the fastest.
Here is sample run. The version using mode-directed tabling is clearly the fastest.
Line 4,270: Line 4,270:
=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
Translation of the pseudo-code in the Wikipedia article:
Translation of the pseudo-code in the Wikipedia article:
<lang PicoLisp>(de levenshtein (A B)
<syntaxhighlight lang=PicoLisp>(de levenshtein (A B)
(let D
(let D
(cons
(cons
Line 4,287: Line 4,287:
(get D J (inc I))
(get D J (inc I))
(get D (inc J) I)
(get D (inc J) I)
(get D J I) ) ) ) ) ) ) ) )</lang>
(get D J I) ) ) ) ) ) ) ) )</syntaxhighlight>
or, using 'map' to avoid list indexing:
or, using 'map' to avoid list indexing:
<lang PicoLisp>(de levenshtein (A B)
<syntaxhighlight lang=PicoLisp>(de levenshtein (A B)
(let D
(let D
(cons
(cons
Line 4,308: Line 4,308:
(cadr Y) ) )
(cadr Y) ) )
B
B
D ) ) )</lang>
D ) ) )</syntaxhighlight>
{{out|Output (both cases)}}
{{out|Output (both cases)}}
<pre>: (levenshtein (chop "kitten") (chop "sitting"))
<pre>: (levenshtein (chop "kitten") (chop "sitting"))
Line 4,315: Line 4,315:
=={{header|PL/I}}==
=={{header|PL/I}}==
===version 1===
===version 1===
<lang pli>*process source xref attributes or(!);
<syntaxhighlight lang=pli>*process source xref attributes or(!);
lsht: Proc Options(main);
lsht: Proc Options(main);
Call test('kitten' ,'sitting');
Call test('kitten' ,'sitting');
Line 4,370: Line 4,370:
Return(ld);
Return(ld);
End;
End;
End;</lang>
End;</syntaxhighlight>
{{out}}
{{out}}
<pre> 1st string = >kitten<
<pre> 1st string = >kitten<
Line 4,396: Line 4,396:
Levenshtein distance = 3</pre>
Levenshtein distance = 3</pre>
===version 2 recursive with memoization===
===version 2 recursive with memoization===
<lang pli>*process source attributes xref or(!);
<syntaxhighlight lang=pli>*process source attributes xref or(!);
ld3: Proc Options(main);
ld3: Proc Options(main);
Dcl ld(0:30,0:30) Bin Fixed(31);
Dcl ld(0:30,0:30) Bin Fixed(31);
Line 4,440: Line 4,440:
Return(ld(sl,tl));
Return(ld(sl,tl));
End;
End;
End;</lang>
End;</syntaxhighlight>
Output is the same as for version 1.
Output is the same as for version 1.


Line 4,446: Line 4,446:
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
{{Trans|Action!}}
{{Trans|Action!}}
<lang pli>100H: /* CALCULATE THE LEVENSHTEIN DISTANCE BETWEEN STRINGS */
<syntaxhighlight lang=pli>100H: /* CALCULATE THE LEVENSHTEIN DISTANCE BETWEEN STRINGS */
/* TRANS:ATED FROM THE ACTION! SAMPLE */
/* TRANS:ATED FROM THE ACTION! SAMPLE */


Line 4,545: Line 4,545:
CALL TEST( .( 'ACTION', 33, '$' ), .'PL/M$' );
CALL TEST( .( 'ACTION', 33, '$' ), .'PL/M$' );


EOF</lang>
EOF</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 4,556: Line 4,556:
=={{header|PowerShell}}==
=={{header|PowerShell}}==
This version does not allow empty strings.
This version does not allow empty strings.
<lang PowerShell>
<syntaxhighlight lang=PowerShell>
function Get-LevenshteinDistance
function Get-LevenshteinDistance
{
{
Line 4,616: Line 4,616:
$outputObject
$outputObject
}
}
</syntaxhighlight>
</lang>
<lang PowerShell>
<syntaxhighlight lang=PowerShell>
Get-LevenshteinDistance "kitten" "sitting"
Get-LevenshteinDistance "kitten" "sitting"
Get-LevenshteinDistance rosettacode raisethysword
Get-LevenshteinDistance rosettacode raisethysword
</syntaxhighlight>
</lang>
{{Out}}
{{Out}}
<pre>
<pre>
Line 4,630: Line 4,630:


=={{header|Processing}}==
=={{header|Processing}}==
<lang processing>void setup() {
<syntaxhighlight lang=processing>void setup() {
println(distance("kitten", "sitting"));
println(distance("kitten", "sitting"));
}
}
Line 4,647: Line 4,647:
}
}
return costs[b.length()];
return costs[b.length()];
}</lang>
}</syntaxhighlight>


==={{header|Processing Python mode}}===
==={{header|Processing Python mode}}===


<lang python>def setup():
<syntaxhighlight lang=python>def setup():
println(distance("kitten", "sitting"))
println(distance("kitten", "sitting"))


Line 4,667: Line 4,667:
costs[j] = cj
costs[j] = cj


return costs[len(b)]</lang>
return costs[len(b)]</syntaxhighlight>


=={{header|Prolog}}==
=={{header|Prolog}}==
Line 4,673: Line 4,673:
Works with SWI-Prolog.<br>
Works with SWI-Prolog.<br>
Based on Wikipedia's pseudocode.
Based on Wikipedia's pseudocode.
<lang Prolog>levenshtein(S, T, R) :-
<syntaxhighlight lang=Prolog>levenshtein(S, T, R) :-
length(S, M),
length(S, M),
M1 is M+1,
M1 is M+1,
Line 4,733: Line 4,733:


init_n(N, L) :-
init_n(N, L) :-
nth0(0, L, N).</lang>
nth0(0, L, N).</syntaxhighlight>
{{out|Output examples}}
{{out|Output examples}}
<pre> ?- levenshtein("kitten", "sitting", R).
<pre> ?- levenshtein("kitten", "sitting", R).
Line 4,763: Line 4,763:
=={{header|PureBasic}}==
=={{header|PureBasic}}==
Based on Wikipedia's pseudocode.
Based on Wikipedia's pseudocode.
<lang PureBasic>Procedure LevenshteinDistance(A_string$, B_String$)
<syntaxhighlight lang=PureBasic>Procedure LevenshteinDistance(A_string$, B_String$)
Protected m, n, i, j, min, k, l
Protected m, n, i, j, min, k, l
m = Len(A_string$)
m = Len(A_string$)
Line 4,791: Line 4,791:
;- Testing
;- Testing
n = LevenshteinDistance("kitten", "sitting")
n = LevenshteinDistance("kitten", "sitting")
MessageRequester("Info","Levenshtein Distance= "+Str(n))</lang>
MessageRequester("Info","Levenshtein Distance= "+Str(n))</syntaxhighlight>


=={{header|Python}}==
=={{header|Python}}==
===Iterative 1===
===Iterative 1===
Faithful implementation of "Iterative with full matrix" from Wikipedia
Faithful implementation of "Iterative with full matrix" from Wikipedia
<lang python>def levenshteinDistance(str1, str2):
<syntaxhighlight lang=python>def levenshteinDistance(str1, str2):
m = len(str1)
m = len(str1)
n = len(str2)
n = len(str2)
Line 4,813: Line 4,813:


print(levenshteinDistance("kitten","sitting"))
print(levenshteinDistance("kitten","sitting"))
print(levenshteinDistance("rosettacode","raisethysword"))</lang>
print(levenshteinDistance("rosettacode","raisethysword"))</syntaxhighlight>
{{out}}
{{out}}
<pre>3
<pre>3
Line 4,820: Line 4,820:
===Iterative 2===
===Iterative 2===
Implementation of the Wikipedia algorithm, optimized for memory
Implementation of the Wikipedia algorithm, optimized for memory
<lang python>def minimumEditDistance(s1,s2):
<syntaxhighlight lang=python>def minimumEditDistance(s1,s2):
if len(s1) > len(s2):
if len(s1) > len(s2):
s1,s2 = s2,s1
s1,s2 = s2,s1
Line 4,837: Line 4,837:
print(minimumEditDistance("kitten","sitting"))
print(minimumEditDistance("kitten","sitting"))
print(minimumEditDistance("rosettacode","raisethysword"))</lang>
print(minimumEditDistance("rosettacode","raisethysword"))</syntaxhighlight>
{{out}}
{{out}}
<pre>3
<pre>3
Line 4,844: Line 4,844:
===Iterative 3===
===Iterative 3===
Iterative space optimized (even bounded)
Iterative space optimized (even bounded)
<lang python>def ld(a, b, mx=-1):
<syntaxhighlight lang=python>def ld(a, b, mx=-1):
def result(d): return d if mx < 0 else False if d > mx else True
def result(d): return d if mx < 0 else False if d > mx else True
Line 4,885: Line 4,885:
ld('kitten','kittenaaaaaaaaaaaaaaaaa',3), # False
ld('kitten','kittenaaaaaaaaaaaaaaaaa',3), # False
ld('kittenaaaaaaaaaaaaaaaaa','kitten',3) # False
ld('kittenaaaaaaaaaaaaaaaaa','kitten',3) # False
)</lang>
)</syntaxhighlight>
{{out}}
{{out}}
<pre>0 1 2 3 4 8 17 17
<pre>0 1 2 3 4 8 17 17
Line 4,893: Line 4,893:
====Memoized recursion====
====Memoized recursion====
(Uses [http://docs.python.org/dev/library/functools.html?highlight=functools.lru_cache#functools.lru_cache this] cache from the standard library).
(Uses [http://docs.python.org/dev/library/functools.html?highlight=functools.lru_cache#functools.lru_cache this] cache from the standard library).
<lang python>>>> from functools import lru_cache
<syntaxhighlight lang=python>>>> from functools import lru_cache
>>> @lru_cache(maxsize=4095)
>>> @lru_cache(maxsize=4095)
def ld(s, t):
def ld(s, t):
Line 4,905: Line 4,905:


>>> print( ld("kitten","sitting"),ld("rosettacode","raisethysword") )
>>> print( ld("kitten","sitting"),ld("rosettacode","raisethysword") )
3 8</lang>
3 8</syntaxhighlight>


====Non-recursive: reduce and scanl====
====Non-recursive: reduce and scanl====
{{Works with|Python|3.7}}
{{Works with|Python|3.7}}
<lang python>'''Levenshtein distance'''
<syntaxhighlight lang=python>'''Levenshtein distance'''


from itertools import (accumulate, chain, islice)
from itertools import (accumulate, chain, islice)
Line 5,055: Line 5,055:
# MAIN ---
# MAIN ---
if __name__ == '__main__':
if __name__ == '__main__':
main()</lang>
main()</syntaxhighlight>
{{Out}}
{{Out}}
<pre>Levenshtein minimum edit distances:
<pre>Levenshtein minimum edit distances:
Line 5,068: Line 5,068:
=={{header|Racket}}==
=={{header|Racket}}==
A memoized recursive implementation.
A memoized recursive implementation.
<lang racket>#lang racket
<syntaxhighlight lang=racket>#lang racket


(define (levenshtein a b)
(define (levenshtein a b)
Line 5,087: Line 5,087:


(levenshtein "kitten" "sitting")
(levenshtein "kitten" "sitting")
(levenshtein "rosettacode" "raisethysword")</lang>
(levenshtein "rosettacode" "raisethysword")</syntaxhighlight>
{{out}}
{{out}}
<pre>3
<pre>3
Line 5,096: Line 5,096:


Implementation of the Wikipedia algorithm. Since column 0 and row 0 are used for base distances, the original algorithm would require us to compare "@s[$i-1] eq @t[$j-1]", and reference $m and $n separately. Prepending an unused value (undef) onto @s and @t makes their indices align with the $i,$j numbering of @d, and lets us use .end instead of $m,$n.
Implementation of the Wikipedia algorithm. Since column 0 and row 0 are used for base distances, the original algorithm would require us to compare "@s[$i-1] eq @t[$j-1]", and reference $m and $n separately. Prepending an unused value (undef) onto @s and @t makes their indices align with the $i,$j numbering of @d, and lets us use .end instead of $m,$n.
<lang perl6>sub levenshtein-distance ( Str $s, Str $t --> Int ) {
<syntaxhighlight lang=perl6>sub levenshtein-distance ( Str $s, Str $t --> Int ) {
my @s = *, |$s.comb;
my @s = *, |$s.comb;
my @t = *, |$t.comb;
my @t = *, |$t.comb;
Line 5,118: Line 5,118:
for <kitten sitting>, <saturday sunday>, <rosettacode raisethysword> -> ($s, $t) {
for <kitten sitting>, <saturday sunday>, <rosettacode raisethysword> -> ($s, $t) {
say "Levenshtein distance('$s', '$t') == ", levenshtein-distance($s, $t)
say "Levenshtein distance('$s', '$t') == ", levenshtein-distance($s, $t)
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>Levenshtein distance('kitten', 'sitting') == 3
<pre>Levenshtein distance('kitten', 'sitting') == 3
Line 5,127: Line 5,127:
===version 1===
===version 1===
As per the task's requirements, this version includes a driver to display the results.
As per the task's requirements, this version includes a driver to display the results.
<lang rexx>/*REXX program calculates and displays the Levenshtein distance between two strings. */
<syntaxhighlight lang=rexx>/*REXX program calculates and displays the Levenshtein distance between two strings. */
call Levenshtein 'kitten' , "sitting"
call Levenshtein 'kitten' , "sitting"
call Levenshtein 'rosettacode' , "raisethysword"
call Levenshtein 'rosettacode' , "raisethysword"
Line 5,146: Line 5,146:
end /*k*/
end /*k*/
end /*j*/ /* [↑] best choice.*/
end /*j*/ /* [↑] best choice.*/
say ' Levenshtein distance = ' @.oL.tL; say; return</lang>
say ' Levenshtein distance = ' @.oL.tL; say; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default inputs:}}
{{out|output|text=&nbsp; when using the internal default inputs:}}
<pre>
<pre>
Line 5,172: Line 5,172:
===version 2===
===version 2===
<strike>same as</strike> Similar to version 1 <strike>(but does not include a driver for testing)</strike>, reformatted and commented
<strike>same as</strike> Similar to version 1 <strike>(but does not include a driver for testing)</strike>, reformatted and commented
<lang rexx>
<syntaxhighlight lang=rexx>
/*rexx*/
/*rexx*/


Line 5,226: Line 5,226:
say 'Levenshtein distance = ' d.m.n; say ''
say 'Levenshtein distance = ' d.m.n; say ''
Return d.m.n
Return d.m.n
</syntaxhighlight>
</lang>
{{output}}
{{output}}
<pre>
<pre>
Line 5,280: Line 5,280:
===version 3===
===version 3===
Alternate algorithm from Wikipedia <strike>(but does not include a driver for testing)</strike>.
Alternate algorithm from Wikipedia <strike>(but does not include a driver for testing)</strike>.
<lang rexx>
<syntaxhighlight lang=rexx>
/*rexx*/
/*rexx*/


Line 5,326: Line 5,326:
End
End
return v1.tl
return v1.tl
</syntaxhighlight>
</lang>
{{output}}
{{output}}
<pre>
<pre>
Line 5,356: Line 5,356:
===version 4 (recursive)===
===version 4 (recursive)===
Recursive algorithm from Wikipedia with memoization
Recursive algorithm from Wikipedia with memoization
<lang rexx>
<syntaxhighlight lang=rexx>
/*rexx*/
/*rexx*/


Line 5,399: Line 5,399:
End
End
Return ld.sl.tl
Return ld.sl.tl
</syntaxhighlight>
</lang>
{{output}}
{{output}}
<pre>
<pre>
Line 5,428: Line 5,428:


=={{header|Ring}}==
=={{header|Ring}}==
<lang ring>
<syntaxhighlight lang=ring>
# Project : Levenshtein distance
# Project : Levenshtein distance


Line 5,468: Line 5,468:
levenshteindistance = d[n][m]
levenshteindistance = d[n][m]
return levenshteindistance
return levenshteindistance
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 5,481: Line 5,481:
and for <code>k >= j</code> contains ''lev(i-1, k)''. The inner loop body restores the invariant for the
and for <code>k >= j</code> contains ''lev(i-1, k)''. The inner loop body restores the invariant for the
new value of <code>j</code>.
new value of <code>j</code>.
<lang ruby>module Levenshtein
<syntaxhighlight lang=ruby>module Levenshtein
def self.distance(a, b)
def self.distance(a, b)
Line 5,503: Line 5,503:
end
end


Levenshtein.test</lang>
Levenshtein.test</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 5,512: Line 5,512:
A variant can be found used in Rubygems [https://github.com/rubygems/rubygems/blob/master/lib/rubygems/text.rb]
A variant can be found used in Rubygems [https://github.com/rubygems/rubygems/blob/master/lib/rubygems/text.rb]


<lang ruby>def levenshtein_distance(str1, str2)
<syntaxhighlight lang=ruby>def levenshtein_distance(str1, str2)
n = str1.length
n = str1.length
m = str2.length
m = str2.length
Line 5,545: Line 5,545:
%w{kitten sitting saturday sunday rosettacode raisethysword}.each_slice(2) do |a, b|
%w{kitten sitting saturday sunday rosettacode raisethysword}.each_slice(2) do |a, b|
puts "distance(#{a}, #{b}) = #{levenshtein_distance(a, b)}"
puts "distance(#{a}, #{b}) = #{levenshtein_distance(a, b)}"
end</lang>
end</syntaxhighlight>
same output
same output


=={{header|Run BASIC}}==
=={{header|Run BASIC}}==
<lang runbasic>print levenshteinDistance("kitten", "sitting")
<syntaxhighlight lang=runbasic>print levenshteinDistance("kitten", "sitting")
print levenshteinDistance("rosettacode", "raisethysword")
print levenshteinDistance("rosettacode", "raisethysword")
end
end
Line 5,580: Line 5,580:
levenshteinDistance = d(n, m)
levenshteinDistance = d(n, m)
[ex]
[ex]
end function</lang>Output:<pre>3
end function</syntaxhighlight>Output:<pre>3
8</pre>
8</pre>


Line 5,586: Line 5,586:
Implementation of the wikipedia algorithm.
Implementation of the wikipedia algorithm.
{{works with|Rust|1.45}}
{{works with|Rust|1.45}}
<lang rust>fn main() {
<syntaxhighlight lang=rust>fn main() {
println!("{}", levenshtein_distance("kitten", "sitting"));
println!("{}", levenshtein_distance("kitten", "sitting"));
println!("{}", levenshtein_distance("saturday", "sunday"));
println!("{}", levenshtein_distance("saturday", "sunday"));
Line 5,617: Line 5,617:
}
}
matrix[word2_length-1][word1_length-1]
matrix[word2_length-1][word1_length-1]
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>3
<pre>3
Line 5,625: Line 5,625:
=={{header|Scala}}==
=={{header|Scala}}==
===Translated Wikipedia algorithm.===
===Translated Wikipedia algorithm.===
<lang scala>object Levenshtein0 extends App {
<syntaxhighlight lang=scala>object Levenshtein0 extends App {


def distance(s1: String, s2: String): Int = {
def distance(s1: String, s2: String): Int = {
Line 5,648: Line 5,648:
printDistance("rosettacode", "raisethysword")
printDistance("rosettacode", "raisethysword")


}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>kitten -> sitting : 3
<pre>kitten -> sitting : 3
Line 5,654: Line 5,654:
===Functional programmed, memoized===
===Functional programmed, memoized===
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/zj7bHC7/0 (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/qHhDWl68QgWv1uwOYzzNqw Scastie (remote JVM)].
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/zj7bHC7/0 (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/qHhDWl68QgWv1uwOYzzNqw Scastie (remote JVM)].
<lang Scala>import scala.collection.mutable
<syntaxhighlight lang=Scala>import scala.collection.mutable
import scala.collection.parallel.ParSeq
import scala.collection.parallel.ParSeq


Line 5,687: Line 5,687:
printDistance("sleep", "fleeting")
printDistance("sleep", "fleeting")


}</lang>
}</syntaxhighlight>


=={{header|Scheme}}==
=={{header|Scheme}}==
Line 5,693: Line 5,693:
Recursive version from wikipedia article.
Recursive version from wikipedia article.


<lang scheme>
<syntaxhighlight lang=scheme>
(define (levenshtein s t)
(define (levenshtein s t)
(define (%levenshtein s sl t tl)
(define (%levenshtein s sl t tl)
Line 5,707: Line 5,707:
(string->list t)
(string->list t)
(string-length t)))
(string-length t)))
</syntaxhighlight>
</lang>


{{out}}
{{out}}
Line 5,718: Line 5,718:


=={{header|Seed7}}==
=={{header|Seed7}}==
<lang seed7>$ include "seed7_05.s7i";
<syntaxhighlight lang=seed7>$ include "seed7_05.s7i";


const func integer: levenshteinDistance (in string: s, in string: t) is func
const func integer: levenshteinDistance (in string: s, in string: t) is func
Line 5,749: Line 5,749:
writeln("kitten -> sitting: " <& levenshteinDistance("kitten", "sitting"));
writeln("kitten -> sitting: " <& levenshteinDistance("kitten", "sitting"));
writeln("rosettacode -> raisethysword: " <& levenshteinDistance("rosettacode", "raisethysword"));
writeln("rosettacode -> raisethysword: " <& levenshteinDistance("rosettacode", "raisethysword"));
end func;</lang>
end func;</syntaxhighlight>


{{out}}
{{out}}
Line 5,759: Line 5,759:
=={{header|SenseTalk}}==
=={{header|SenseTalk}}==
SenseTalk has a built-in TextDifference function for this.
SenseTalk has a built-in TextDifference function for this.
<lang SenseTalk>
<syntaxhighlight lang=SenseTalk>
put textDifference("kitten", "sitting") // --> 3
put textDifference("kitten", "sitting") // --> 3
put textDifference("rosettacode", "raisethysword") // --> 8
put textDifference("rosettacode", "raisethysword") // --> 8


</syntaxhighlight>
</lang>


=={{header|SequenceL}}==
=={{header|SequenceL}}==
This implementation is based on the "Iterative with two matrix rows" version on Wikipedia.
This implementation is based on the "Iterative with two matrix rows" version on Wikipedia.
<lang sequenceL>
<syntaxhighlight lang=sequenceL>
import <Utilities/Sequence.sl>;
import <Utilities/Sequence.sl>;
import <Utilities/Math.sl>;
import <Utilities/Math.sl>;
Line 5,789: Line 5,789:
min(min(v1[n] + 1, v0[n + 1] + 1), v0[n] + (0 when s = t[n] else 1))),
min(min(v1[n] + 1, v0[n + 1] + 1), v0[n] + (0 when s = t[n] else 1))),
n + 1);
n + 1);
</syntaxhighlight>
</lang>


=={{header|Sidef}}==
=={{header|Sidef}}==
===Recursive===
===Recursive===
<lang ruby>func lev(s, t) is cached {
<syntaxhighlight lang=ruby>func lev(s, t) is cached {
 
 
s || return t.len
s || return t.len
Line 5,807: Line 5,807:
__FUNC__(s1, t )
__FUNC__(s1, t )
)
)
}</lang>
}</syntaxhighlight>


===Iterative===
===Iterative===
<lang ruby>func lev(s, t) {
<syntaxhighlight lang=ruby>func lev(s, t) {
var d = [@(0 .. t.len), s.len.of {[_]}...]
var d = [@(0 .. t.len), s.len.of {[_]}...]
for i,j in (^s ~X ^t) {
for i,j in (^s ~X ^t) {
Line 5,820: Line 5,820:
}
}
d[-1][-1]
d[-1][-1]
}</lang>
}</syntaxhighlight>


Calling the function:
Calling the function:
<lang ruby>say lev(%c'kitten', %c'sitting'); # prints: 3
<syntaxhighlight lang=ruby>say lev(%c'kitten', %c'sitting'); # prints: 3
say lev(%c'rosettacode', %c'raisethysword'); # prints: 8</lang>
say lev(%c'rosettacode', %c'raisethysword'); # prints: 8</syntaxhighlight>


=={{header|Simula}}==
=={{header|Simula}}==
<lang simula>BEGIN
<syntaxhighlight lang=simula>BEGIN


INTEGER PROCEDURE LEVENSHTEINDISTANCE(S1, S2); TEXT S1, S2;
INTEGER PROCEDURE LEVENSHTEINDISTANCE(S1, S2); TEXT S1, S2;
Line 5,863: Line 5,863:


END
END
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>
<pre>
Line 5,875: Line 5,875:
{{works with|Smalltalk/X}}
{{works with|Smalltalk/X}}
ST/X provides a customizable levenshtein method in the String class (weights for individual operations can be passed in):
ST/X provides a customizable levenshtein method in the String class (weights for individual operations can be passed in):
<lang smalltalk>'kitten' levenshteinTo: 'sitting' s:1 k:1 c:1 i:1 d:1 -> 3
<syntaxhighlight lang=smalltalk>'kitten' levenshteinTo: 'sitting' s:1 k:1 c:1 i:1 d:1 -> 3
'rosettacode' levenshteinTo: 'raisethysword' s:1 k:1 c:1 i:1 d:1 -> 8</lang>
'rosettacode' levenshteinTo: 'raisethysword' s:1 k:1 c:1 i:1 d:1 -> 8</syntaxhighlight>


=={{header|Swift}}==
=={{header|Swift}}==
Line 5,882: Line 5,882:
Version using entire matrix:
Version using entire matrix:


<lang swift>func levDis(w1: String, w2: String) -> Int {
<syntaxhighlight lang=swift>func levDis(w1: String, w2: String) -> Int {
let (t, s) = (w1.characters, w2.characters)
let (t, s) = (w1.characters, w2.characters)
Line 5,896: Line 5,896:
}
}
return mat.last!.last!
return mat.last!.last!
}</lang>
}</syntaxhighlight>


Version using only two rows at a time:
Version using only two rows at a time:


<lang swift>func levDis(w1: String, w2: String) -> Int {
<syntaxhighlight lang=swift>func levDis(w1: String, w2: String) -> Int {
let (t, s) = (w1.characters, w2.characters)
let (t, s) = (w1.characters, w2.characters)
Line 5,915: Line 5,915:
}
}
return last.last!
return last.last!
}</lang>
}</syntaxhighlight>


===Single array version===
===Single array version===
{{trans|C++}}
{{trans|C++}}
<lang swift>func levenshteinDistance(string1: String, string2: String) -> Int {
<syntaxhighlight lang=swift>func levenshteinDistance(string1: String, string2: String) -> Int {
let m = string1.count
let m = string1.count
let n = string2.count
let n = string2.count
Line 5,945: Line 5,945:
}
}


print(levenshteinDistance(string1: "rosettacode", string2: "raisethysword"))</lang>
print(levenshteinDistance(string1: "rosettacode", string2: "raisethysword"))</syntaxhighlight>


{{out}}
{{out}}
Line 5,953: Line 5,953:


=={{header|Tcl}}==
=={{header|Tcl}}==
<lang tcl>proc levenshteinDistance {s t} {
<syntaxhighlight lang=tcl>proc levenshteinDistance {s t} {
# Edge cases
# Edge cases
if {![set n [string length $t]]} {
if {![set n [string length $t]]} {
Line 5,981: Line 5,981:
# The score is at the end of the last-computed row
# The score is at the end of the last-computed row
return [lindex $p end]
return [lindex $p end]
}</lang>
}</syntaxhighlight>
{{out|Usage}}
{{out|Usage}}
<lang tcl>puts [levenshteinDistance "kitten" "sitting"]; # Prints 3</lang>
<syntaxhighlight lang=tcl>puts [levenshteinDistance "kitten" "sitting"]; # Prints 3</syntaxhighlight>


=={{header|TSE SAL}}==
=={{header|TSE SAL}}==
<lang TSESAL>// library: math: get: damerau: levenshtein <description></description> <version>1.0.0.0.23</version> <version control></version control> (filenamemacro=getmadle.s) [kn, ri, th, 08-09-2011 23:04:55]
<syntaxhighlight lang=TSESAL>// library: math: get: damerau: levenshtein <description></description> <version>1.0.0.0.23</version> <version control></version control> (filenamemacro=getmadle.s) [kn, ri, th, 08-09-2011 23:04:55]
INTEGER PROC FNMathGetDamerauLevenshteinDistanceI( STRING s1, STRING s2 )
INTEGER PROC FNMathGetDamerauLevenshteinDistanceI( STRING s1, STRING s2 )
INTEGER L1 = Length( s1 )
INTEGER L1 = Length( s1 )
Line 6,020: Line 6,020:
s2 = "altruistic"
s2 = "altruistic"
Warn( "Minimum amount of steps to convert ", s1, " to ", s2, " = ", FNMathGetDamerauLevenshteinDistanceI( s1, s2 ) ) // gives e.g. 6
Warn( "Minimum amount of steps to convert ", s1, " to ", s2, " = ", FNMathGetDamerauLevenshteinDistanceI( s1, s2 ) ) // gives e.g. 6
END</lang>
END</syntaxhighlight>


=={{header|Turbo-Basic XL}}==
=={{header|Turbo-Basic XL}}==
<lang turbobasic>
<syntaxhighlight lang=turbobasic>
10 DIM Word_1$(20), Word_2$(20), DLDm(21, 21)
10 DIM Word_1$(20), Word_2$(20), DLDm(21, 21)
11 CLS
11 CLS
Line 6,059: Line 6,059:
11846 ? "Damerau Distance=";Result
11846 ? "Damerau Distance=";Result
11850 ENDPROC
11850 ENDPROC
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>kitten, sitting: 3
<pre>kitten, sitting: 3
Line 6,066: Line 6,066:


=={{header|TUSCRIPT}}==
=={{header|TUSCRIPT}}==
<lang tuscript>
<syntaxhighlight lang=tuscript>
$$ MODE TUSCRIPT
$$ MODE TUSCRIPT
distance=DISTANCE ("kitten", "sitting")
distance=DISTANCE ("kitten", "sitting")
PRINT distance
PRINT distance
</syntaxhighlight>
</lang>
Output:
Output:
<pre>
<pre>
Line 6,078: Line 6,078:
=={{header|TypeScript}}==
=={{header|TypeScript}}==
{{Trans|JavaScript}}
{{Trans|JavaScript}}
<lang typescript>
<syntaxhighlight lang=typescript>
function levenshtein(a: string, b: string): number {
function levenshtein(a: string, b: string): number {
const m: number = a.length,
const m: number = a.length,
Line 6,094: Line 6,094:
}
}


</syntaxhighlight>
</lang>


=={{header|Vala}}==
=={{header|Vala}}==
<lang vala>class LevenshteinDistance : Object {
<syntaxhighlight lang=vala>class LevenshteinDistance : Object {
public static int compute (owned string s, owned string t, bool case_sensitive = false) {
public static int compute (owned string s, owned string t, bool case_sensitive = false) {
var n = s.length;
var n = s.length;
Line 6,123: Line 6,123:
}
}
}
}
</syntaxhighlight>
</lang>


=={{header|VBA}}==
=={{header|VBA}}==
{{trans|Phix}}<lang vb>Option Base 1
{{trans|Phix}}<syntaxhighlight lang=vb>Option Base 1
Function levenshtein(s1 As String, s2 As String) As Integer
Function levenshtein(s1 As String, s2 As String) As Integer
Dim n As Integer: n = Len(s1) + 1
Dim n As Integer: n = Len(s1) + 1
Line 6,166: Line 6,166:
Debug.Print levenshtein("kitten", "sitting")
Debug.Print levenshtein("kitten", "sitting")
Debug.Print levenshtein("rosettacode", "raisethysword")
Debug.Print levenshtein("rosettacode", "raisethysword")
End Sub</lang>{{out}}
End Sub</syntaxhighlight>{{out}}
<pre> 3
<pre> 3
8 </pre>
8 </pre>


=={{header|VBScript}}==
=={{header|VBScript}}==
<lang vb>' Levenshtein distance - 23/04/2020
<syntaxhighlight lang=vb>' Levenshtein distance - 23/04/2020


Function Min(a,b)
Function Min(a,b)
Line 6,214: Line 6,214:
PrintLevenshtein "rosettacode", "raisethysword"
PrintLevenshtein "rosettacode", "raisethysword"
PrintLevenshtein "saturday", "sunday"
PrintLevenshtein "saturday", "sunday"
PrintLevenshtein "sleep", "fleeting"</lang>
PrintLevenshtein "sleep", "fleeting"</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 6,231: Line 6,231:
{{works with|VBA|6.5}}
{{works with|VBA|6.5}}
{{works with|VBA|7.1}}
{{works with|VBA|7.1}}
<lang vb>Function min(x As Integer, y As Integer) As Integer
<syntaxhighlight lang=vb>Function min(x As Integer, y As Integer) As Integer
If x < y Then
If x < y Then
min = x
min = x
Line 6,291: Line 6,291:
Debug.Print "'sleep' to 'fleeting' => "; levenshtein("sleep", "fleeting")
Debug.Print "'sleep' to 'fleeting' => "; levenshtein("sleep", "fleeting")
End Sub
End Sub
</syntaxhighlight>
</lang>
{{out}}
{{out}}
<pre>'kitten' to 'sitting' => 3
<pre>'kitten' to 'sitting' => 3
Line 6,299: Line 6,299:


=={{header|Visual Basic .NET}}==
=={{header|Visual Basic .NET}}==
<lang vbnet> Function LevenshteinDistance(ByVal String1 As String, ByVal String2 As String) As Integer
<syntaxhighlight lang=vbnet> Function LevenshteinDistance(ByVal String1 As String, ByVal String2 As String) As Integer
Dim Matrix(String1.Length, String2.Length) As Integer
Dim Matrix(String1.Length, String2.Length) As Integer
Dim Key As Integer
Dim Key As Integer
Line 6,318: Line 6,318:
Next
Next
Return Matrix(String1.Length - 1, String2.Length - 1)
Return Matrix(String1.Length - 1, String2.Length - 1)
End Function</lang>
End Function</syntaxhighlight>


=={{header|Wren}}==
=={{header|Wren}}==
{{trans|Go}}
{{trans|Go}}
<lang ecmascript>var levenshtein = Fn.new { |s, t|
<syntaxhighlight lang=ecmascript>var levenshtein = Fn.new { |s, t|
var ls = s.count
var ls = s.count
var lt = t.count
var lt = t.count
Line 6,346: Line 6,346:
}
}


System.print(levenshtein.call("kitten", "sitting"))</lang>
System.print(levenshtein.call("kitten", "sitting"))</syntaxhighlight>


{{out}}
{{out}}
Line 6,355: Line 6,355:
=={{header|zkl}}==
=={{header|zkl}}==
{{trans|D}}
{{trans|D}}
<lang zkl>fcn levenshtein(s1,s2){
<syntaxhighlight lang=zkl>fcn levenshtein(s1,s2){
sz2,costs:=s2.len() + 1, List.createLong(sz2,0); // -->zero filled List
sz2,costs:=s2.len() + 1, List.createLong(sz2,0); // -->zero filled List
foreach i in (s1.len() + 1){
foreach i in (s1.len() + 1){
Line 6,372: Line 6,372:
}
}
costs[-1]
costs[-1]
}</lang>
}</syntaxhighlight>
<lang zkl>foreach a,b in (T(T("kitten","sitting"), T("rosettacode","raisethysword"),
<syntaxhighlight lang=zkl>foreach a,b in (T(T("kitten","sitting"), T("rosettacode","raisethysword"),
T("yo",""), T("","yo"), T("abc","abc")) ){
T("yo",""), T("","yo"), T("abc","abc")) ){
println(a," --> ",b,": ",levenshtein(a,b));
println(a," --> ",b,": ",levenshtein(a,b));
}</lang>
}</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>
Line 6,387: Line 6,387:


=={{header|ZX Spectrum Basic}}==
=={{header|ZX Spectrum Basic}}==
<lang zxbasic>10 REM ZX Spectrum Basic - Levenshtein distance
<syntaxhighlight lang=zxbasic>10 REM ZX Spectrum Basic - Levenshtein distance
20 INPUT "first word:",n$
20 INPUT "first word:",n$
30 INPUT "second word:",m$
30 INPUT "second word:",m$
Line 6,400: Line 6,400:
120 NEXT i
120 NEXT i
130 NEXT j
130 NEXT j
140 PRINT "The Levenshtein distance between """;n$;""", """;m$;""" is ";d(m+1,n+1);"."</lang>
140 PRINT "The Levenshtein distance between """;n$;""", """;m$;""" is ";d(m+1,n+1);"."</syntaxhighlight>
{{out}}
{{out}}
<pre>
<pre>