Levenshtein distance: Difference between revisions

Add bruijn
m (→‎Iterative: should be ===, not ==)
(Add bruijn)
 
(20 intermediate revisions by 14 users not shown)
Line 31:
{{trans|Python}}
 
<syntaxhighlight lang="11l">F minimumEditDistance(=s1, =s2)
I s1.len > s2.len
(s1, s2) = (s2, s1)
Line 57:
 
=={{header|360 Assembly}}==
<syntaxhighlight lang="360asm">* Levenshtein distance - 22/04/2020
LEVENS CSECT
USING LEVENS,R13 base register
Line 241:
=={{header|Action!}}==
{{Improve||The output shown does not appear to match the PrintF calls in the code}}
<syntaxhighlight lang="action">
DEFINE STRING="CHAR ARRAY" ; sys.act
DEFINE width="15" ; max characters 14
Line 327:
 
=={{header|Ada}}==
<syntaxhighlight lang=Ada"ada">with Ada.Text_IO;
 
procedure Main is
Line 367:
=={{header|Aime}}==
{{trans|C}}
<syntaxhighlight lang="aime">integer
dist(data s, t, integer i, j, list d)
{
Line 421:
<br>
Non-recursive algorithm - although Algol 68 supports recursion, Action! doesn't.
<syntaxhighlight lang="algol68"># Calculate Levenshtein distance between strings - translated from the Action! sample #
BEGIN
 
Line 482:
===Iteration===
Translation of the "fast" C-version
<syntaxhighlight lang=AppleScript"applescript">set dist to findLevenshteinDistance for "sunday" against "saturday"
to findLevenshteinDistance for s1 against s2
script o
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:
<syntaxhighlight lang=AppleScript"applescript">-- levenshtein :: String -> String -> Int
on levenshtein(sa, sb)
set {s1, s2} to {characters of sa, characters of sb}
Line 698:
end zip3</syntaxhighlight>
{{Out}}
<syntaxhighlight lang=AppleScript"applescript">{3, 3, 8, 8}</syntaxhighlight>
 
=={{header|Arc}}==
Line 704:
O(n * m) time, linear space, using lists instead of vectors
 
<syntaxhighlight lang="lisp">(def levenshtein (str1 str2)
(withs l1 len.str1
l2 len.str2
Line 723:
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">print levenshtein "kitten" "sitting"</syntaxhighlight>
 
{{out}}
Line 731:
=={{header|AutoHotkey}}==
{{trans|Go}}
<syntaxhighlight lang=AutoHotkey"autohotkey">levenshtein(s, t){
If s =
return StrLen(t)
Line 755:
Slavishly copied from the very clear AutoHotKey example.
 
<syntaxhighlight lang="awk">#!/usr/bin/awk -f
 
BEGIN {
Line 810:
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):
<syntaxhighlight lang="awk">#!/usr/bin/awk -f
 
function levdist(str1, str2, l1, l2, tog, arr, i, j, a, b, c) {
Line 841:
 
=={{header|BBC BASIC}}==
<syntaxhighlight lang="bbcbasic"> PRINT "'kitten' -> 'sitting' has distance " ;
PRINT ; FNlevenshtein("kitten", "sitting")
PRINT "'rosettacode' -> 'raisethysword' has distance " ;
Line 877:
=={{header|BQN}}==
Recursive slow version:
<syntaxhighlight lang=BQN"bqn">Levenshtein ← {
𝕨 𝕊"": ≠𝕨;
""𝕊 𝕩: ≠𝕩;
Line 885:
}</syntaxhighlight>
Fast version:
<syntaxhighlight lang=BQN"bqn">Levenshtein ← @⊸∾⊸{¯1⊑(↕≠𝕨)𝕨{(1⊸+⊸⌊`1⊸+⌊⊑⊸»+𝕨≠𝕗˙)𝕩}´⌽𝕩}</syntaxhighlight>
{{out|Example use}}
<syntaxhighlight lang="text"> "kitten" Levenshtein "sitting"
3
"Saturday" Levenshtein "Sunday"
Line 897:
{{trans|C}}
Recursive method, but with memoization.
<syntaxhighlight lang="bracmat">(levenshtein=
lev cache
. ( lev
Line 927:
levenshtein$(rosettacode,raisethysword)
8</pre>
 
=={{header|Bruijn}}==
{{trans|Haskell}}
Recursive and non-memoized method:
 
<syntaxhighlight lang="bruijn>
:import std/Combinator .
:import std/Char C
:import std/List .
:import std/Math .
 
levenshtein y [[[∅?1 ∀0 (∅?0 ∀1 (0 (1 [[[[go]]]])))]]]
go (C.eq? 3 1) (6 2 0) ++(lmin ((6 2 0) : ((6 5 0) : {}(6 2 4))))
 
:test ((levenshtein "rosettacode" "raisethysword") =? (+8)) ([[1]])
:test ((levenshtein "kitten" "sitting") =? (+3)) ([[1]])
</syntaxhighlight>
 
=={{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>.
<syntaxhighlight lang=C"c">#include <stdio.h>
#include <string.h>
 
Line 976 ⟶ 993:
}</syntaxhighlight>
Take the above and add caching, we get (in [[C99]]):
<syntaxhighlight lang="c">#include <stdio.h>
#include <string.h>
 
Line 1,023 ⟶ 1,040:
=={{header|C sharp|C#}}==
This is a straightforward translation of the Wikipedia pseudocode.
<syntaxhighlight lang="csharp">using System;
 
namespace LevenshteinDistance
Line 1,083 ⟶ 1,100:
 
=={{header|C++}}==
<syntaxhighlight lang="c">#include <string>
#include <iostream>
using namespace std;
Line 1,145 ⟶ 1,162:
 
===Generic ISO C++ version===
<syntaxhighlight lang="cpp">#include <algorithm>
#include <iostream>
#include <numeric>
Line 1,194 ⟶ 1,211:
 
===Recursive Version===
<syntaxhighlight lang="lisp">(defn levenshtein [str1 str2]
(let [len1 (count str1)
len2 (count str2)]
Line 1,211 ⟶ 1,228:
 
===Iterative version===
<syntaxhighlight lang="lisp">(defn levenshtein [w1 w2]
(letfn [(cell-value [same-char? prev-row cur-row col-idx]
(min (inc (nth prev-row col-idx))
Line 1,234 ⟶ 1,251:
 
=={{header|CLU}}==
<syntaxhighlight lang="clu">min = proc [T: type] (a, b: T) returns (T)
where T has lt: proctype (T,T) returns (bool)
if a<b
Line 1,284 ⟶ 1,301:
=={{header|COBOL}}==
GnuCobol 2.2
<syntaxhighlight lang="cobol">
identification division.
program-id. Levenshtein.
Line 1,356 ⟶ 1,373:
 
=={{header|CoffeeScript}}==
<syntaxhighlight lang="coffeescript">levenshtein = (str1, str2) ->
# more of less ported simple algorithm from JS
m = str1.length
Line 1,388 ⟶ 1,405:
 
=={{header|Common Lisp}}==
<syntaxhighlight lang="lisp">(defun levenshtein (a b)
(let* ((la (length a))
(lb (length b))
Line 1,398 ⟶ 1,415:
((aref rec x y) (aref rec x y))
(t (setf (aref rec x y)
(min (+ (if (char= (char aleven (1- la x)) (char b (- lb y))) 0 1)
(min+ (leven x (1- xy)) y1)
(+ (leven (1- x) (1- y)) (if (char= (levenchar a (- la x)) (char b (1- lb y))) 0 1))))))))
(leven (1- x) (1- y)))))))))
(leven la lb))))
 
Line 1,410 ⟶ 1,426:
=={{header|Crystal}}==
The standard library includes [https://crystal-lang.org/api/0.19.2/Levenshtein.html levenshtein] module
<syntaxhighlight lang="ruby">require "levenshtein"
puts Levenshtein.distance("kitten", "sitting")
puts Levenshtein.distance("rosettacode", "raisethysword")
Line 1,419 ⟶ 1,435:
 
{{trans|Ruby 1st version}}
<syntaxhighlight lang="ruby">module Levenshtein
def self.distance(a, b)
Line 1,451 ⟶ 1,467:
 
{{trans|Ruby 2nd version}}
<syntaxhighlight lang="ruby">def levenshtein_distance(str1, str2)
n, m = str1.size, str2.size
max = n / 2
Line 1,493 ⟶ 1,509:
===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:
<syntaxhighlight lang="d">void main() {
import std.stdio, std.algorithm;
 
Line 1,503 ⟶ 1,519:
===Iterative Version===
{{trans|Java}}
<syntaxhighlight lang="d">import std.stdio, std.algorithm;
 
int distance(in string s1, in string s2) pure nothrow {
Line 1,538 ⟶ 1,554:
===Memoized Recursive Version===
{{trans|Python}}
<syntaxhighlight lang="d">import std.stdio, std.array, std.algorithm, std.functional;
 
uint lDist(T)(in const(T)[] s, in const(T)[] t) nothrow {
Line 1,556 ⟶ 1,572:
=={{header|Delphi}}==
{{Trans|C#}}
<syntaxhighlight lang=Delphi"delphi">
program Levenshtein_distanceTest;
 
Line 1,626 ⟶ 1,642:
=={{header|DWScript}}==
Based on Wikipedia version
<syntaxhighlight lang="delphi">function LevenshteinDistance(s, t : String) : Integer;
var
i, j : Integer;
Line 1,652 ⟶ 1,668:
=={{header|Dyalect}}==
 
<syntaxhighlight lang="dyalect">func levenshtein(s, t) {
var n = s.Length()
var m = t.Length()
Line 1,700 ⟶ 1,716:
 
<pre>rosettacode -> raisethysword = 8</pre>
 
=={{header|EasyLang}}==
{{trans|AWK}}
 
<syntaxhighlight lang=easylang>
func dist s1$ s2$ .
if len s1$ = 0
return len s2$
.
if len s2$ = 0
return len s1$
.
c1$ = substr s1$ 1 1
c2$ = substr s2$ 1 1
s1rest$ = substr s1$ 2 len s1$
s2rest$ = substr s2$ 2 len s2$
#
if c1$ = c2$
return dist s1rest$ s2rest$
.
min = lower dist s1rest$ s2rest$ dist s1$ s2rest$
min = lower min dist s1rest$ s2rest$
return min + 1
.
print dist "kitten" "sitting"
print dist "rosettacode" "raisethysword"
</syntaxhighlight>
 
=={{header|EchoLisp}}==
<syntaxhighlight lang="lisp">
;; Recursive version adapted from Clojure
;; Added necessary memoization
Line 1,736 ⟶ 1,779:
This code is translated from Haskell version.
 
<syntaxhighlight lang="ela">open list
 
levenshtein s1 s2 = last <| foldl transform [0 .. length s1] s2
Line 1,744 ⟶ 1,787:
Executing:
 
<syntaxhighlight lang="ela">(levenshtein "kitten" "sitting", levenshtein "rosettacode" "raisethysword")</syntaxhighlight>
{{out}}
<pre>(3, 8)</pre>
Line 1,750 ⟶ 1,793:
=={{header|Elixir}}==
{{trans|Ruby}}
<syntaxhighlight lang="elixir">defmodule Levenshtein do
def distance(a, b) do
ta = String.downcase(a) |> to_charlist |> List.to_tuple
Line 1,788 ⟶ 1,831:
=={{header|Erlang}}==
Here are two implementations. The first is the naive version, the second is a memoized version using Erlang's dictionary datatype.
<syntaxhighlight lang="erlang">
-module(levenshtein).
-compile(export_all).
Line 1,826 ⟶ 1,869:
</syntaxhighlight>
Below is a comparison of the runtimes, measured in microseconds, between the two implementations.
<syntaxhighlight lang="erlang">
68> timer:tc(levenshtein,distance,["rosettacode","raisethysword"]).
{774799,8} % {Time, Result}
Line 1,838 ⟶ 1,881:
 
=={{header|ERRE}}==
<syntaxhighlight lang=ERRE"erre">
PROGRAM LEVENSHTEIN
 
Line 1,890 ⟶ 1,933:
=={{header|Euphoria}}==
Code by Jeremy Cowgar from the [http://www.rapideuphoria.com/cgi-bin/asearch.exu?gen=on&keywords=Levenshtein Euphoria File Archive].
<syntaxhighlight lang="euphoria">function min(sequence s)
atom m
m = s[1]
Line 1,944 ⟶ 1,987:
=={{header|F_Sharp|F#}}==
=== Standard version ===
<syntaxhighlight lang=FSharp"fsharp">
open System
 
Line 1,980 ⟶ 2,023:
 
=== Recursive Version ===
<syntaxhighlight lang=FSharp"fsharp">
open System
 
Line 2,006 ⟶ 2,049:
 
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: lcs prettyprint ;
"kitten" "sitting" levenshtein .</syntaxhighlight>
{{out}}
Line 2,015 ⟶ 2,058:
=={{header|Forth}}==
{{trans|C}}
<syntaxhighlight lang="forth">: levenshtein ( a1 n1 a2 n2 -- n3)
dup \ if either string is empty, difference
if \ is inserting all chars from the other
Line 2,040 ⟶ 2,083:
 
=={{header|Fortran}}==
<syntaxhighlight lang=Fortran"fortran">
program demo_edit_distance
character(len=:),allocatable :: sources(:),targets(:)
Line 2,092 ⟶ 2,135:
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
' Uses the "iterative with two matrix rows" algorithm
Line 2,151 ⟶ 2,194:
=={{header|Frink}}==
Frink has a built-in function to calculate the Levenshtein edit distance between two strings:
<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.
 
=={{header|FutureBasic}}==
Recursive version.
Based on Wikipedia algorithm. Suitable for Pascal strings.
<syntaxhighlight lang="futurebasic">window 1
local fn LevenshteinDistance( s1 as CFStringRef, s2 as CFStringRef ) as NSInteger
 
NSInteger result
local fn LevenshteinDistance( aStr as Str255, bStr as Str255 ) as long
dim as long m, n, i, j, min, k, l
dim as long distance( 255, 255 )
// If strings are equal, Levenshtein distance is 0
m = len$(aStr)
if ( fn StringIsEqual( s1, s2 ) ) then result = 0 : exit fn
n = len$(bStr)
// If either string is empty, then distance is the length of the other string.
for i = 0 to m
if ( distancelen(s1) i,== 0 ) then result = ilen(s2) : exit fn
if ( len(s2) == 0) then result = len(s1) : exit fn
next
// The remaining recursive process uses first characters and remainder of each string.
for j = 0 to n
CFStringRef s1First = fn StringSubstringToIndex( s1, 1 )
distance( 0, j ) = j
CFStringRef s2First = fn StringSubstringToIndex( s2, 1 )
next
CFStringRef s1Rest = mid( s1, 1, len(s1) -1 )
CFStringRef s2Rest = mid( s2, 1, len(s2) -1 )
// If leading characters are the same, then distance is that between the rest of the strings.
for j = 1 to n
if fn StringIsEqual( s1First, s2First ) then result = fn LevenshteinDistance( s1Rest, s2Rest ) : exit fn
for i = 1 to m
if mid$( aStr, i, 1 ) == mid$( bStr, j, 1 )
// Find the distances between sub strings.
distance( i, j ) = distance( i-1, j-1 )
NSInteger distA = fn LevenshteinDistance( s1Rest, s2 )
else
NSInteger distB = fn min = distanceLevenshteinDistance( i-1s1, j ) +s2Rest 1)
NSInteger distC = fn LevenshteinDistance( s1Rest, s2Rest )
k = distance( i, j - 1 ) + 1
l = distance( i-1, j-1 ) + 1
// Return the minimum distance between substrings.
if k < min then min = k
NSInteger minDist = distA
if l < min then min = l
if ( distB < minDist ) distance(then i, j )minDist = mindistB
if ( distC < minDist ) then minDist = distC
end if
result = minDist + 1 // Include change for the first character.
next
end fn = result
next
end fn = distance( m, n )
 
dim as long i
dim as Str255 testStr( 5, 2 )
 
NSInteger i
testStr( 0, 0 ) = "kitten" : testStr( 0, 1 ) = "sitting"
testStr( 1, 0 ) = "rosettacode" :CFStringRef testStr( 16, 12 ) = "raisethysword"
testStr( 2, 0 ) = "Saturday" : testStr( 2, 1 ) = "Sunday"
testStr( 3, 0 ) = "FutureBasic" : testStr( 3, 1 ) = "FutureBasic"
testStr( 4, 0 ) = "here's a bunch of words"
testStr( 4, 1 ) = "to wring out this code"
 
testStr( 0, 0 ) = @"kitten" : testStr( 0, 1 ) = @"sitting"
for i = 0 to 4
testStr( 1, print0 "1st string) = @";rosettacode" : testStr( i1, 01 ) = @"raisethysword"
testStr( 2, print0 "2nd string) = @";Saturday" : testStr( i2, 1 ) = @"Sunday"
print "Levenshtein distance ="; fn LevenshteinDistance( testStr( i3, 0 ), = @"FutureBasic" : testStr( i3, 1 ) )= @"FutureBasic"
testStr( 4, 0 ) = @"rave" : testStr( 4, 1 ) = @"ravel"
testStr( 5, 0 ) = @"black" : testStr( 5, 1 ) = @"slack"
testStr( 6, 0 ) = @"rave" : testStr( 6, 1 ) = @"grave"
 
for i = 0 to 6
print @"1st string = "; testStr( i, 0 )
print @"2nd string = "; testStr( i, 1 )
print @"Levenshtein distance = "; fn LevenshteinDistance( testStr( i, 0 ), testStr( i, 1 ) )
print
next
 
HandleEvents</syntaxhighlight>
</syntaxhighlight>
 
{{output}}
Output:
<pre>
1st string = kitten
Line 2,226 ⟶ 2,271:
Levenshtein distance = 0
 
1st string = here's a bunch of wordsrave
2nd string = to wring out this coderavel
Levenshtein distance = 181
 
1st string = black
2nd string = slack
Levenshtein distance = 1
 
1st string = rave
2nd string = grave
Levenshtein distance = 1
</pre>
 
=={{header|Go}}==
WP algorithm:
<syntaxhighlight lang="go">package main
 
import "fmt"
Line 2,276 ⟶ 2,329:
</pre>
{{trans|C}}
<syntaxhighlight lang="go">package main
 
import "fmt"
Line 2,306 ⟶ 2,359:
 
=={{header|Groovy}}==
<syntaxhighlight lang="groovy">def distance(String str1, String str2) {
def dist = new int[str1.size() + 1][str2.size() + 1]
(0..str1.size()).each { dist[it][0] = it }
Line 2,335 ⟶ 2,388:
 
===Implementation 1===
<syntaxhighlight lang="haskell">levenshtein :: Eq a => [a] -> [a] -> Int
levenshtein s1 s2 = last $ foldl transform [0 .. length s1] s2
where
Line 2,348 ⟶ 2,401:
 
===Implementation 2===
<syntaxhighlight lang="haskell">levenshtein :: Eq a => [a] -> [a] -> Int
levenshtein s1 [] = length s1
levenshtein [] s2 = length s2
Line 2,364 ⟶ 2,417:
 
=={{header|Icon}} and {{header|Unicon}}==
<syntaxhighlight lang="unicon">procedure main()
every process(!&input)
end
Line 2,395 ⟶ 2,448:
=={{header|Io}}==
A <code>levenshtein</code> method is available on strings when the standard <code>Range</code> addon is loaded.
<syntaxhighlight lang="text">Io 20110905
Io> Range ; "kitten" levenshtein("sitting")
==> 3
Line 2,401 ⟶ 2,454:
==> 8
Io> </syntaxhighlight>
 
=={{header|IS-BASIC}}==
<syntaxhighlight lang="is-basic">100 PROGRAM "Levensht.bas"
110 LET S1$="kitten":LET S2$="sitting"
120 PRINT "The Levenshtein distance between """;S1$;""" and """;S2$;""" is:";LEVDIST(S1$,S2$)
130 DEF LEVDIST(S$,T$)
140 LET N=LEN(T$):LET M=LEN(S$)
150 NUMERIC D(0 TO M,0 TO N)
160 FOR I=0 TO M
170 LET D(I,0)=I
180 NEXT
190 FOR J=0 TO N
200 LET D(0,J)=J
210 NEXT
220 FOR J=1 TO N
230 FOR I=1 TO M
240 IF S$(I)=T$(J) THEN
250 LET D(I,J)=D(I-1,J-1)
260 ELSE
270 LET D(I,J)=MIN(D(I-1,J)+1,MIN(D(I,J-1)+1,D(I-1,J-1)+1))
280 END IF
290 NEXT
300 NEXT
310 LET LEVDIST=D(M,N)
320 END DEF</syntaxhighlight>
 
=={{header|J}}==
One approach would be a literal transcription of the [[wp:Levenshtein_distance#Computing_Levenshtein_distance|wikipedia implementation]]:
<syntaxhighlight lang="j">levenshtein=:4 :0
D=. x +/&i.&>:&# y
for_i.1+i.#x do.
Line 2,427 ⟶ 2,505:
We can also do the usual optimization where we only represent one row of the distance matrix at a time:
 
<syntaxhighlight lang="j">levdist =:4 :0
'a b'=. (x;y) /: (#x),(#y)
D=. >: iz =. i.#b
Line 2,436 ⟶ 2,514:
)</syntaxhighlight>
{{out|Example use}}
<syntaxhighlight lang="j"> 'kitten' levenshtein 'sitting'
3
'kitten' levdist 'sitting'
3</syntaxhighlight>
Time and space use:
<syntaxhighlight lang="j">
timespacex '''kitten'' levenshtein ''sitting'''
0.000113 6016
Line 2,451 ⟶ 2,529:
=={{header|Java}}==
Based on the definition for Levenshtein distance given in the Wikipedia article:
<syntaxhighlight lang="java">public class Levenshtein {
 
public static int distance(String a, String b) {
Line 2,485 ⟶ 2,563:
</pre>
{{trans|C}}
<syntaxhighlight lang="java">public class Levenshtein{
public static int levenshtein(String s, String t){
/* if either string is empty, difference is inserting all chars
Line 2,538 ⟶ 2,616:
===Iterative space optimized (even bounded) ===
{{trans|Python}}
<syntaxhighlight lang="java">
import static java.lang.Math.abs;
import static java.lang.Math.max;
Line 2,622 ⟶ 2,700:
===ES5===
Iterative:
<syntaxhighlight lang="javascript">function levenshtein(a, b) {
var t = [], u, i, j, m = a.length, n = b.length;
if (!m) { return n; }
Line 2,658 ⟶ 2,736:
 
By composition of generic functions:
<syntaxhighlight lang=JavaScript"javascript">(() => {
'use strict';
 
Line 2,817 ⟶ 2,895:
67ms for rosettacode/raisethysword
71ms for edocattesor/drowsyhtesiar
<syntaxhighlight lang="jq">
# lookup the distance between s and t in the nested cache,
# which uses basic properties of the Levenshtein distance to save space:
Line 2,870 ⟶ 2,948:
s as $s | t as $t | {} | ld($s;$t) | .[0];</syntaxhighlight>
'''Task'''
<syntaxhighlight lang="jq">def demo:
"levenshteinDistance between \(.[0]) and \(.[1]) is \( levenshteinDistance(.[0]; .[1]) )";
Line 2,886 ⟶ 2,964:
=={{header|Jsish}}==
From Javascript, ES5 entry.
<syntaxhighlight lang="javascript">/* Levenshtein Distance, in Jsish */
 
function levenshtein(a, b) {
Line 2,939 ⟶ 3,017:
'''Recursive''':
{{works with|Julia|1.0}}
<syntaxhighlight lang="julia">function levendist(s::AbstractString, t::AbstractString)
ls, lt = length.((s, t))
ls == 0 && return lt
Line 2,954 ⟶ 3,032:
'''Iterative''':
{{works with|Julia|0.6}}
<syntaxhighlight lang="julia">function levendist1(s::AbstractString, t::AbstractString)
ls, lt = length(s), length(t)
if ls > lt
Line 2,977 ⟶ 3,055:
 
Let's see some benchmark:
<syntaxhighlight lang="julia">using BenchmarkTools
println("\n# levendist(kitten, sitting)")
s, t = "kitten", "sitting"
Line 3,007 ⟶ 3,085:
=={{header|Kotlin}}==
===Standard Version===
<syntaxhighlight lang="scala">// version 1.0.6
 
// Uses the "iterative with two matrix rows" algorithm referred to in the Wikipedia article.
Line 3,049 ⟶ 3,127:
 
===Functional/Folding Version===
<syntaxhighlight lang="scala">
fun levenshtein(s: String, t: String,
charScore : (Char, Char) -> Int = { c1, c2 -> if (c1 == c2) 0 else 1}) : Int {
Line 3,083 ⟶ 3,161:
Suitable for short strings:
 
<syntaxhighlight lang="lisp">
(defun levenshtein-simple
(('() str)
Line 3,101 ⟶ 3,179:
You can copy and paste that function into an LFE REPL and run it like so:
 
<syntaxhighlight lang="lisp">
> (levenshtein-simple "a" "a")
0
Line 3,116 ⟶ 3,194:
=== Cached Implementation ===
 
<syntaxhighlight lang="lisp">
(defun levenshtein-distance (str1 str2)
(let (((tuple distance _) (levenshtein-distance
Line 3,147 ⟶ 3,225:
As before, here's some usage in the REPL. Note that longer strings are now possible to compare without incurring long execution times:
 
<syntaxhighlight lang="lisp">
> (levenshtein-distance "a" "a")
0
Line 3,161 ⟶ 3,239:
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">'Levenshtein Distance translated by Brandon Parker
'08/19/10
'from http://www.merriampark.com/ld.htm#VB
Line 3,210 ⟶ 3,288:
=={{header|Limbo}}==
{{trans|Go}}
<syntaxhighlight lang="limbo">implement Levenshtein;
 
include "sys.m"; sys: Sys;
Line 3,268 ⟶ 3,346:
=={{header|LiveCode}}==
{{trans|Go}}
<syntaxhighlight lang=LiveCode"livecode">
//Code By Neurox66
function Levenshtein pString1 pString2
Line 3,299 ⟶ 3,377:
=={{header|Lobster}}==
{{trans|C}}
<syntaxhighlight lang=Lobster"lobster">def levenshtein(s: string, t: string) -> int:
 
def makeNxM(n: int, m: int, v: int) -> [[int]]:
Line 3,337 ⟶ 3,415:
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">function leven(s,t)
if s == '' then return t:len() end
if t == '' then return s:len() end
Line 3,362 ⟶ 3,440:
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang=M2000"m2000 Interpreterinterpreter">
Module Checkit {
\\ Iterative with two matrix rows
Line 3,432 ⟶ 3,510:
 
=={{header|Maple}}==
<syntaxhighlight lang=Maple"maple">
> with(StringTools):
> Levenshtein("kitten","sitting");
Line 3,442 ⟶ 3,520:
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang=Mathematica"mathematica">EditDistance["kitten","sitting"]
EditDistance["rosettacode","raisethysword"]</syntaxhighlight>
{{out}}
Line 3,449 ⟶ 3,527:
 
=={{header|MATLAB}}==
<syntaxhighlight lang=MATLAB"matlab">
function score = levenshtein(s1, s2)
% score = levenshtein(s1, s2)
Line 3,485 ⟶ 3,563:
=={{header|MiniScript}}==
In the Mini Micro environment, this function is part of the stringUtil library module, and can be used like so:
<syntaxhighlight lang=MiniScript"miniscript">import "stringUtil"
print "kitten".editDistance("sitting")</syntaxhighlight>
 
In environments where the stringUtil module is not available, you'd have to define it yourself:
<syntaxhighlight lang=MiniScript"miniscript">string.editDistance = function(s2)
n = self.len
m = s2.len
Line 3,534 ⟶ 3,612:
 
=={{header|Modula-2}}==
<syntaxhighlight lang="modula2">MODULE LevenshteinDistance;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
FROM Strings IMPORT Length;
Line 3,593 ⟶ 3,671:
=={{header|NetRexx}}==
{{trans|ooRexx}}
<syntaxhighlight lang=NetRexx"netrexx">/* NetRexx */
options replace format comments java crossref symbols nobinary
 
Line 3,654 ⟶ 3,732:
=={{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.
<syntaxhighlight lang="nim">import std/editdistance
 
echo editDistanceAscii("kitten", "sitting")
Line 3,665 ⟶ 3,743:
{{trans|Python}}
Here is a translation of the Python version.
<syntaxhighlight lang="nim">import sequtils
 
func min(a, b, c: int): int {.inline.} = min(a, min(b, c))
Line 3,690 ⟶ 3,768:
echo levenshteinDistance("kitten","sitting")
echo levenshteinDistance("rosettacode","raisethysword")</syntaxhighlight>
 
=={{header|Oberon-2}}==
{{trans|Modula-2}}
<syntaxhighlight lang="oberon2">MODULE LevesteinDistance;
 
IMPORT Out,Strings;
PROCEDURE Levestein(s,t:ARRAY OF CHAR):LONGINT;
CONST
maxlen = 15;
VAR
d:ARRAY maxlen,maxlen OF LONGINT;
lens,lent,i,j:LONGINT;
PROCEDURE Min(a,b:LONGINT):LONGINT;
BEGIN
IF a < b THEN RETURN a ELSE RETURN b END
END Min;
BEGIN
lens := Strings.Length(s);
lent := Strings.Length(t);
IF lens = 0 THEN RETURN lent
ELSIF lent = 0 THEN RETURN lens
ELSE
FOR i := 0 TO lens DO d[i,0] := i END;
FOR j := 0 TO lent DO d[0,j] := j END;
FOR i := 1 TO lens DO
FOR j := 1 TO lent DO
IF s[i-1] = t[j-1] THEN
d[i,j] := d[i-1,j-1]
ELSE
d[i,j] := Min((d[i-1,j] + 1),
Min(d[i,j-1] + 1, d[i-1,j-1] + 1));
END
END
END
END;
RETURN d[lens,lent];
END Levestein;
 
PROCEDURE ShowDistance(s,t:ARRAY OF CHAR);
BEGIN
Out.String(s);
Out.String(" -> ");
Out.String(t);
Out.String(": ");
Out.Int(Levestein(s,t),0);
Out.Ln
END ShowDistance;
BEGIN
ShowDistance("kitten", "sitting");
ShowDistance("rosettacode", "raisethysword");
END LevesteinDistance.
</syntaxhighlight>
 
{{out}}
<pre>kitten -> sitting: 3
rosettacode -> raisethysword: 8
</pre>
 
=={{header|Objeck}}==
{{trans|C#}}
<syntaxhighlight lang="objeck">class Levenshtein {
function : Main(args : String[]) ~ Nil {
if(args->Size() = 2) {
Line 3,730 ⟶ 3,869:
=={{header|Objective-C}}==
Translation of the C# code into a NSString category
<syntaxhighlight lang="objc">@interface NSString (levenshteinDistance)
- (NSUInteger)levenshteinDistanceToString:(NSString *)string;
@end
Line 3,768 ⟶ 3,907:
=={{header|OCaml}}==
Translation of the pseudo-code of the Wikipedia article:
<syntaxhighlight lang="ocaml">let minimum a b c =
min a (min b c)
 
Line 3,811 ⟶ 3,950:
=== A recursive functional version ===
This could be made faster with memoization
<syntaxhighlight lang=OCaml"ocaml">let levenshtein s t =
let rec dist i j = match (i,j) with
| (i,0) -> i
Line 3,835 ⟶ 3,974:
 
=={{header|ooRexx}}==
<syntaxhighlight lang=ooRexx"oorexx">
say "kitten -> sitting:" levenshteinDistance("kitten", "sitting")
say "rosettacode -> raisethysword:" levenshteinDistance("rosettacode", "raisethysword")
Line 3,892 ⟶ 4,031:
{{trans|JavaScript}}
{{Works with|PARI/GP|2.7.4 and above}}
<syntaxhighlight lang="parigp">
\\ Levenshtein distance between two words
\\ 6/21/16 aev
Line 3,930 ⟶ 4,069:
=={{header|Pascal}}==
A fairly direct translation of the wikipedia pseudo code:
<syntaxhighlight lang="pascal">Program LevenshteinDistanceDemo(output);
 
uses
Line 3,976 ⟶ 4,115:
=={{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.
<syntaxhighlight lang=Perl"perl">use List::Util qw(min);
 
my %cache;
Line 4,004 ⟶ 4,143:
Iterative solution:
 
<syntaxhighlight lang="perl">use List::Util qw(min);
 
sub leven {
Line 4,029 ⟶ 4,168:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang=Phix"phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 4,084 ⟶ 4,223:
=== alternative ===
Modelled after the Processing code, uses a single/smaller array, passes the same tests as above.
<!--<syntaxhighlight lang=Phix"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: #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,102 ⟶ 4,241:
 
=={{header|PHP}}==
<syntaxhighlight lang=PHP"php">
echo levenshtein('kitten','sitting');
echo levenshtein('rosettacode', 'raisethysword');
Line 4,114 ⟶ 4,253:
===Iterative===
Based on the iterative algorithm at Wikipedia. Picat is 1-based so some adjustments are needed.
<syntaxhighlight lang=Picat"picat">levenshtein(S,T) = Dist =>
M = 1+S.length,
N = 1+T.length,
Line 4,142 ⟶ 4,281:
 
===Tabled recursive version===
<syntaxhighlight lang=Picat"picat">table
levenshtein_rec(S,T) = Dist =>
Dist1 = 0,
Line 4,163 ⟶ 4,302:
===Mode-directed tabling===
{{trans|Prolog}}
<syntaxhighlight lang=Picat"picat">
levenshtein_mode(S,T) = Dist =>
lev(S, T, Dist).
Line 4,176 ⟶ 4,315:
 
===Test===
<syntaxhighlight lang=Picat"picat">go =>
S = [
Line 4,225 ⟶ 4,364:
===Benchmark on larger strings===
Benchmarking the methods with larger strings of random lengths (between 1 and 2000).
<syntaxhighlight lang=Picat"picat">go2 =>
_ = random2(),
Len = 2000,
Line 4,268 ⟶ 4,407:
=={{header|PicoLisp}}==
Translation of the pseudo-code in the Wikipedia article:
<syntaxhighlight lang=PicoLisp"picolisp">(de levenshtein (A B)
(let D
(cons
Line 4,287 ⟶ 4,426:
(get D J I) ) ) ) ) ) ) ) )</syntaxhighlight>
or, using 'map' to avoid list indexing:
<syntaxhighlight lang=PicoLisp"picolisp">(de levenshtein (A B)
(let D
(cons
Line 4,313 ⟶ 4,452:
=={{header|PL/I}}==
===version 1===
<syntaxhighlight lang="pli">*process source xref attributes or(!);
lsht: Proc Options(main);
Call test('kitten' ,'sitting');
Line 4,394 ⟶ 4,533:
Levenshtein distance = 3</pre>
===version 2 recursive with memoization===
<syntaxhighlight lang="pli">*process source attributes xref or(!);
ld3: Proc Options(main);
Dcl ld(0:30,0:30) Bin Fixed(31);
Line 4,444 ⟶ 4,583:
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
{{Trans|Action!}}
<syntaxhighlight lang="pli">100H: /* CALCULATE THE LEVENSHTEIN DISTANCE BETWEEN STRINGS */
/* TRANS:ATED FROM THE ACTION! SAMPLE */
 
Line 4,554 ⟶ 4,693:
=={{header|PowerShell}}==
This version does not allow empty strings.
<syntaxhighlight lang=PowerShell"powershell">
function Get-LevenshteinDistance
{
Line 4,615 ⟶ 4,754:
}
</syntaxhighlight>
<syntaxhighlight lang=PowerShell"powershell">
Get-LevenshteinDistance "kitten" "sitting"
Get-LevenshteinDistance rosettacode raisethysword
Line 4,628 ⟶ 4,767:
 
=={{header|Processing}}==
<syntaxhighlight lang="processing">void setup() {
println(distance("kitten", "sitting"));
}
Line 4,649 ⟶ 4,788:
==={{header|Processing Python mode}}===
 
<syntaxhighlight lang="python">def setup():
println(distance("kitten", "sitting"))
 
Line 4,671 ⟶ 4,810:
Works with SWI-Prolog.<br>
Based on Wikipedia's pseudocode.
<syntaxhighlight lang=Prolog"prolog">levenshtein(S, T, R) :-
length(S, M),
M1 is M+1,
Line 4,761 ⟶ 4,900:
=={{header|PureBasic}}==
Based on Wikipedia's pseudocode.
<syntaxhighlight lang=PureBasic"purebasic">Procedure LevenshteinDistance(A_string$, B_String$)
Protected m, n, i, j, min, k, l
m = Len(A_string$)
Line 4,794 ⟶ 4,933:
===Iterative 1===
Faithful implementation of "Iterative with full matrix" from Wikipedia
<syntaxhighlight lang="python">def levenshteinDistance(str1, str2):
m = len(str1)
n = len(str2)
Line 4,818 ⟶ 4,957:
===Iterative 2===
Implementation of the Wikipedia algorithm, optimized for memory
<syntaxhighlight lang="python">def minimumEditDistance(s1,s2):
if len(s1) > len(s2):
s1,s2 = s2,s1
Line 4,842 ⟶ 4,981:
===Iterative 3===
Iterative space optimized (even bounded)
<syntaxhighlight lang="python">def ld(a, b, mx=-1):
def result(d): return d if mx < 0 else False if d > mx else True
Line 4,891 ⟶ 5,030:
====Memoized recursion====
(Uses [http://docs.python.org/dev/library/functools.html?highlight=functools.lru_cache#functools.lru_cache this] cache from the standard library).
<syntaxhighlight lang="python">>>> from functools import lru_cache
>>> @lru_cache(maxsize=4095)
def ld(s, t):
Line 4,907 ⟶ 5,046:
====Non-recursive: reduce and scanl====
{{Works with|Python|3.7}}
<syntaxhighlight lang="python">'''Levenshtein distance'''
 
from itertools import (accumulate, chain, islice)
Line 5,066 ⟶ 5,205:
=={{header|Racket}}==
A memoized recursive implementation.
<syntaxhighlight lang="racket">#lang racket
 
(define (levenshtein a b)
Line 5,094 ⟶ 5,233:
 
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.
<syntaxhighlight lang=perl6"raku" line>sub levenshtein-distance ( Str $s, Str $t --> Int ) {
my @s = *, |$s.comb;
my @t = *, |$t.comb;
Line 5,121 ⟶ 5,260:
Levenshtein distance('saturday', 'sunday') == 3
Levenshtein distance('rosettacode', 'raisethysword') == 8</pre>
 
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
= <Show ('kitten') ('sitting')>
<Show ('rosettacode') ('raisethysword')>;
};
 
Show {
(e.A) (e.B) = <Prout e.A ' -> ' e.B ': ' <Lev (e.A) (e.B)>>;
};
 
Lev {
(e.A) (), <Lenw e.A>: s.L e.A = s.L;
() (e.B), <Lenw e.B>: s.L e.B = s.L;
(s.C e.A) (s.C e.B) = <Lev (e.A) (e.B)>;
(e.A) (e.B), e.A: s.HA e.LA, e.B: s.HB e.LB =
<+ 1 <Min <Lev (e.LA) (e.B)>
<Lev (e.A) (e.LB)>
<Lev (e.LA) (e.LB)>>>;
}
 
Min {
s.N = s.N;
s.M s.N e.X, <Compare s.M s.N>: {
'-' = <Min s.M e.X>;
s.X = <Min s.N e.X>;
};
};</syntaxhighlight>
{{out}}
<pre>kitten -> sitting: 3
rosettacode -> raisethysword: 8</pre>
 
=={{header|REXX}}==
===version 1===
As per the task's requirements, this version includes a driver to display the results.
<syntaxhighlight lang="rexx">/*REXX program calculates and displays the Levenshtein distance between two strings. */
call Levenshtein 'kitten' , "sitting"
call Levenshtein 'rosettacode' , "raisethysword"
Line 5,170 ⟶ 5,340:
===version 2===
<strike>same as</strike> Similar to version 1 <strike>(but does not include a driver for testing)</strike>, reformatted and commented
<syntaxhighlight lang="rexx">
/*rexx*/
 
Line 5,278 ⟶ 5,448:
===version 3===
Alternate algorithm from Wikipedia <strike>(but does not include a driver for testing)</strike>.
<syntaxhighlight lang="rexx">
/*rexx*/
 
Line 5,354 ⟶ 5,524:
===version 4 (recursive)===
Recursive algorithm from Wikipedia with memoization
<syntaxhighlight lang="rexx">
/*rexx*/
 
Line 5,426 ⟶ 5,596:
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Levenshtein distance
 
Line 5,472 ⟶ 5,642:
distance(saturday, sunday) = 3
distance(rosettacode, raisethysword) = 8
</pre>
 
=={{header|RPL}}==
{{works with|HP|28}}
{| class="wikitable"
! RPL code
! Comment
|-
|
≪ DUP2 SIZE SWAP SIZE → a b lb la
≪ '''IF''' la lb * NOT '''THEN''' la lb +
'''ELSE'''
a 2 la SUB b 2 lb SUB DUP2 <span style="color:blue">LEV</span>
'''IF''' a 1 1 SUB b 1 1 SUB == '''THEN'''
ROT ROT DROP2
'''ELSE'''
a ROT <span style="color:blue">LEV</span> ROT b <span style="color:blue">LEV</span>
MIN MIN 1 +
'''END END'''
≫ ≫ '<span style="color:blue">LEV</span>' STO
|
<span style="color:blue">LEV</span> ''( "a" "b" → distance )''
if |a|=0 or [b|=0 then return resp. [b| or |a|
else
put tail(a), tail(b) and lev(tail(a),tail(b)) in stack
if a[1]=b[1} then
clean stack and return lev(tail(a),tail(b))
else
put lev(a,tail(b)) and lev(tail(a),b) in stack
return min of the 3 values in stack and add 1
|}
"kitten" "sitting" <span style="color:blue">LEV</span>
"Summer" "Winter" <span style="color:blue">LEV</span>
"Levenshtein" "Levenshtein" <span style="color:blue">LEV</span>
{{out}}
<pre>
3: 3
2: 4
1: 0
</pre>
 
===Iterative implementation (Wagner-Fischer algorithm)===
 
index of arrays and strings start with 1 in RPL, so the main trick in translating the algorithm given by Wikipedia was to manage the offsets properly. The distance between "rosettacode" and "raisethysword" is within the reach of a calculator (emulated or not), unlike the above recursive approach.
{{works with|HP|48}}
{| class="wikitable"
! RPL code
! Comment
|-
|
DUP2 { } + + ≪ SIZE ≫ DOLIST 1 ADD 0 CON → a b d
≪ 1 a SIZE '''FOR''' h
'd' h 1 + 1 2 →LIST h PUT '''NEXT'''
1 b SIZE '''FOR''' j
'd' 1 j 1 + 2 →LIST j PUT '''NEXT'''
1 b SIZE '''FOR''' j
1 a SIZE '''FOR''' h
a h DUP SUB b j DUP SUB ≠
'd' h j 2 →LIST GET +
'd' h j 1 + 2 →LIST GET 1 +
'd' h 1 + j 2 →LIST GET 1 +
MIN MIN 'd' h 1 + j 1 + 2 →LIST ROT PUT
'''NEXT NEXT'''
'd' DUP SIZE GET
≫ ≫ '<span style="color:blue">LEV2</span>' STO
|
<span style="color:blue">LEV2</span> ''( "a" "b" → distance )''
declare int d[0..m, 0..n] and set each element in d to zero
for h from 1 to m: <span style="color:grey>// h replaces i, which is √-1 in RPL</span>
d[h, 0] := i <span style="color:grey>// RPL array indexes start with 1</span>
for j from 1 to n:
d[0, j] := j
for j from 1 to n:
for h from 1 to m:
substitutionCost := ( s[h] <> t[j] )
d[h, j] := minimum(d[h-1, j-1] + substitutionCost,
d[h-1, j] + 1,
d[h, j-1] + 1)
return d[m, n]
|}
"rosettacode" "raisethysword" <span style="color:blue">LEV2</span>
{{out}}
<pre>
1: 8
</pre>
 
Line 5,479 ⟶ 5,739:
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>.
<syntaxhighlight lang="ruby">module Levenshtein
def self.distance(a, b)
Line 5,510 ⟶ 5,770:
A variant can be found used in Rubygems [https://github.com/rubygems/rubygems/blob/master/lib/rubygems/text.rb]
 
<syntaxhighlight lang="ruby">def levenshtein_distance(str1, str2)
n = str1.length
m = str2.length
Line 5,547 ⟶ 5,807:
 
=={{header|Run BASIC}}==
<syntaxhighlight lang="runbasic">print levenshteinDistance("kitten", "sitting")
print levenshteinDistance("rosettacode", "raisethysword")
end
Line 5,584 ⟶ 5,844:
Implementation of the wikipedia algorithm.
{{works with|Rust|1.45}}
<syntaxhighlight lang="rust">fn main() {
println!("{}", levenshtein_distance("kitten", "sitting"));
println!("{}", levenshtein_distance("saturday", "sunday"));
Line 5,623 ⟶ 5,883:
=={{header|Scala}}==
===Translated Wikipedia algorithm.===
<syntaxhighlight lang="scala">object Levenshtein0 extends App {
 
def distance(s1: String, s2: String): Int = {
Line 5,652 ⟶ 5,912:
===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)].
<syntaxhighlight lang=Scala"scala">import scala.collection.mutable
import scala.collection.parallel.ParSeq
 
Line 5,691 ⟶ 5,951:
Recursive version from wikipedia article.
 
<syntaxhighlight lang="scheme">
(define (levenshtein s t)
(define (%levenshtein s sl t tl)
Line 5,716 ⟶ 5,976:
 
=={{header|Seed7}}==
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const func integer: levenshteinDistance (in string: s, in string: t) is func
Line 5,757 ⟶ 6,017:
=={{header|SenseTalk}}==
SenseTalk has a built-in TextDifference function for this.
<syntaxhighlight lang=SenseTalk"sensetalk">
put textDifference("kitten", "sitting") // --> 3
put textDifference("rosettacode", "raisethysword") // --> 8
Line 5,765 ⟶ 6,025:
=={{header|SequenceL}}==
This implementation is based on the "Iterative with two matrix rows" version on Wikipedia.
<syntaxhighlight lang=sequenceL"sequencel">
import <Utilities/Sequence.sl>;
import <Utilities/Math.sl>;
Line 5,791 ⟶ 6,051:
=={{header|Sidef}}==
===Recursive===
<syntaxhighlight lang="ruby">func lev(s, t) is cached {
 
s || return t.len
t || return s.len
 
var s1 = s.ftslice(1)
var t1 = t.ftslice(1)
 
s[0] == t[0] ? __FUNC__(s1, t1)
Line 5,808 ⟶ 6,068:
 
===Iterative===
<syntaxhighlight lang="ruby">func lev(s, t) {
var d = [@(0 .. t.len), s.len.of {[_]}...]
for i,j in (^s ~X ^t) {
Line 5,821 ⟶ 6,081:
 
Calling the function:
<syntaxhighlight lang="ruby">say lev(%c'kitten', %c'sitting'); # prints: 3
say lev(%c'rosettacode', %c'raisethysword'); # prints: 8</syntaxhighlight>
 
=={{header|Simula}}==
<syntaxhighlight lang="simula">BEGIN
 
INTEGER PROCEDURE LEVENSHTEINDISTANCE(S1, S2); TEXT S1, S2;
Line 5,873 ⟶ 6,133:
{{works with|Smalltalk/X}}
ST/X provides a customizable levenshtein method in the String class (weights for individual operations can be passed in):
<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</syntaxhighlight>
 
Line 5,880 ⟶ 6,140:
Version using entire matrix:
 
<syntaxhighlight lang="swift">func levDis(w1: String, w2: String) -> Int {
let (t, s) = (w1.characters, w2.characters)
Line 5,898 ⟶ 6,158:
Version using only two rows at a time:
 
<syntaxhighlight lang="swift">func levDis(w1: String, w2: String) -> Int {
let (t, s) = (w1.characters, w2.characters)
Line 5,917 ⟶ 6,177:
===Single array version===
{{trans|C++}}
<syntaxhighlight lang="swift">func levenshteinDistance(string1: String, string2: String) -> Int {
let m = string1.count
let n = string2.count
Line 5,951 ⟶ 6,211:
 
=={{header|Tcl}}==
<syntaxhighlight lang="tcl">proc levenshteinDistance {s t} {
# Edge cases
if {![set n [string length $t]]} {
Line 5,981 ⟶ 6,241:
}</syntaxhighlight>
{{out|Usage}}
<syntaxhighlight lang="tcl">puts [levenshteinDistance "kitten" "sitting"]; # Prints 3</syntaxhighlight>
 
=={{header|TSE SAL}}==
<syntaxhighlight lang=TSESAL"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 L1 = Length( s1 )
Line 6,021 ⟶ 6,281:
 
=={{header|Turbo-Basic XL}}==
<syntaxhighlight lang="turbobasic">
10 DIM Word_1$(20), Word_2$(20), DLDm(21, 21)
11 CLS
Line 6,064 ⟶ 6,324:
 
=={{header|TUSCRIPT}}==
<syntaxhighlight lang="tuscript">
$$ MODE TUSCRIPT
distance=DISTANCE ("kitten", "sitting")
Line 6,076 ⟶ 6,336:
=={{header|TypeScript}}==
{{Trans|JavaScript}}
<syntaxhighlight lang="typescript">
function levenshtein(a: string, b: string): number {
const m: number = a.length,
Line 6,092 ⟶ 6,352:
}
 
</syntaxhighlight>
 
=={{header|uBasic/4tH}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="ubasic-4th">
' Uses the "iterative with two matrix rows" algorithm
' referred to in the Wikipedia article.
 
' create two integer arrays of distances
Dim @u(128) ' previous
Dim @v(128) ' current
 
Print "'kitten' to 'sitting' => ";
Print FUNC(_Levenshtein ("kitten", "sitting"))
 
Print "'rosettacode' to 'raisethysword' => ";
Print FUNC(_Levenshtein ("rosettacode", "raisethysword"))
 
Print "'sleep' to 'fleeting' => ";
Print FUNC(_Levenshtein ("sleep", "fleeting"))
 
End
 
_Levenshtein
Param (2)
Local (3)
 
' degenerate cases
If Comp(a@, b@) = 0 Then Return (0)
If Len(a@) = 0 Then Return (Len(b@))
If Len(b@) = 0 Then Return (Len(a@))
 
' initialize v0
For c@ = 0 To Len(b@)
@u(c@) = c@
Next
 
For c@ = 0 To Len(a@) - 1
' calculate @v() from @u()
@v(0) = c@ + 1
For d@ = 0 To Len(b@) - 1
e@ = IIf(Peek (a@, c@) = Peek (b@, d@), 0, 1)
@v(d@ + 1) = min(@v(d@) + 1, Min(@u(d@ + 1) + 1, @u(d@) + e@))
Next
 
' copy @v() to @u() for next iteration
For d@ = 0 To Len(b@)
@u(d@) = @v(d@)
Next
Next
 
Return (@v(Len(b@)))
</syntaxhighlight>
 
=={{header|Vala}}==
<syntaxhighlight lang="vala">class LevenshteinDistance : Object {
public static int compute (owned string s, owned string t, bool case_sensitive = false) {
var n = s.length;
Line 6,124 ⟶ 6,437:
 
=={{header|VBA}}==
{{trans|Phix}}<syntaxhighlight lang="vb">Option Base 1
Function levenshtein(s1 As String, s2 As String) As Integer
Dim n As Integer: n = Len(s1) + 1
Line 6,169 ⟶ 6,482:
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">' Levenshtein distance - 23/04/2020
 
Function Min(a,b)
Line 6,229 ⟶ 6,542:
{{works with|VBA|6.5}}
{{works with|VBA|7.1}}
<syntaxhighlight lang="vb">Function min(x As Integer, y As Integer) As Integer
If x < y Then
min = x
Line 6,291 ⟶ 6,604:
</syntaxhighlight>
{{out}}
<pre>
<pre>'kitten' to 'sitting' => 3
'kitten' to 'sitting' => 3
'sitting' to 'kitten' => 3
'rosettacode' to 'raisethysword' => 8
'sleep' to 'fleeting' => 5</pre>
</pre>
 
=={{header|Visual Basic .NET}}==
<syntaxhighlight lang="vbnet"> Function LevenshteinDistance(ByVal String1 As String, ByVal String2 As String) As Integer
Dim Matrix(String1.Length, String2.Length) As Integer
Dim Key As Integer
Line 6,317 ⟶ 6,632:
Return Matrix(String1.Length - 1, String2.Length - 1)
End Function</syntaxhighlight>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="Zig">
import strings
 
fn main() {
println(strings.levenshtein_distance("kitten", "sitting"))
println(strings.levenshtein_distance("rosettacode", "raisethysword"))
}
</syntaxhighlight>
 
{{out}}
<pre>
3
8
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
<syntaxhighlight lang=ecmascript"wren">var levenshtein = Fn.new { |s, t|
var ls = s.count
var lt = t.count
Line 6,350 ⟶ 6,681:
3
</pre>
 
=={{header|Zig}}==
{{trans|C}}
 
'''Works with:''' 0.11.x, 0.12.0-dev.1381+61861ef39
 
For 0.10.x, replace @min(a, b, c) with std.math.min3(a, b, c).
 
Recursive method without memoization.
 
<syntaxhighlight lang="zig">const std = @import("std");
 
fn levenshtein(s: []const u8, t: []const u8) usize {
// If either string is empty, difference is inserting all chars
// from the other
if (s.len == 0) return t.len;
if (t.len == 0) return s.len;
 
// If last letters are the same, the difference is whatever is
// required to edit the rest of the strings
if (s[s.len - 1] == t[t.len - 1])
return levenshtein(s[0 .. s.len - 1], t[0 .. t.len - 1]);
 
// Else try:
// changing last letter of s to that of t; or
// remove last letter of s; or
// remove last letter of t,
// any of which is 1 edit plus editing the rest of the strings
const a = levenshtein(s[0 .. s.len - 1], t[0 .. t.len - 1]);
const b = levenshtein(s, t[0 .. t.len - 1]);
const c = levenshtein(s[0 .. s.len - 1], t);
 
return @min(a, b, c) + 1;
}
 
pub fn main() std.fs.File.WriteError!void {
const stdout = std.io.getStdOut();
const stdout_w = stdout.writer();
 
const s1 = "rosettacode";
const s2 = "raisethysword";
try stdout_w.print("distance between '{s}' and '{s}': {d}\n", .{ s1, s2, levenshtein(s1, s2) });
return;
}</syntaxhighlight>
 
=={{header|zkl}}==
{{trans|D}}
<syntaxhighlight lang="zkl">fcn levenshtein(s1,s2){
sz2,costs:=s2.len() + 1, List.createLong(sz2,0); // -->zero filled List
foreach i in (s1.len() + 1){
Line 6,371 ⟶ 6,746:
costs[-1]
}</syntaxhighlight>
<syntaxhighlight lang="zkl">foreach a,b in (T(T("kitten","sitting"), T("rosettacode","raisethysword"),
T("yo",""), T("","yo"), T("abc","abc")) ){
println(a," --> ",b,": ",levenshtein(a,b));
Line 6,385 ⟶ 6,760:
 
=={{header|ZX Spectrum Basic}}==
<syntaxhighlight lang="zxbasic">10 REM ZX Spectrum Basic - Levenshtein distance
20 INPUT "first word:",n$
30 INPUT "second word:",m$
55

edits