**Levenshtein** **distantzia,** **hitzen arteko distantzia** edo **edizio-distantzia** zenbaki bat da hitz batetik abiatuta beste hitz bat lortzeko egin behar diren gutxieneko eragiketen kopurua dena, informazioaren teorian eta informatikan oso erabilia da. Eragiketa horietako bakoitza hiru mota hauetako bat izan behar da: karaktere bat txertatzea, ezabatzea edo ordezkatzea. Distantzia honek Vladimir Levenshtein zientzialari errusiarraren omenez jaso zuen izen hori, 1965ean asmatu zuen distantzia neurtzeko neurri hori. Bi karaktere-kateen arteko antzekotasuna erabili behar duten programetan erabilgarria da, zuzentzaile ortografikoekin esate baterako.

Adibidez, "eman" eta "emongo" hitzen arteko distantzia 3 da, gutxienez oinarrizko hiru edizio behar baitira batetik abiatuta bestea lortzeko.

1. eman → emon ('a'-ren ordez 'o' jarrita)
2. emon → emong ('g' bat gehitzea bukaeran)
3. emong → emongo ('o' bat gehitzea bukaeran)

Hamming-en distantziaren orokortze gisa ikusi ohi da, luzera bereko kateetarako erabiltzen dena eta eragiketa moduan 'ordezkatzea' soilik hartzen duena. Levenshteinen distantziaren beste orokortze batzuk badira, esate baterako, Damerau-Levenshtein distantzia, bi karaktereen arteko trukea eragiketa bakar gisa hartzen duena.

'Distantzia' ona denez, propietate hauek betetzen ditu (formalki frogatzea zaila den arren):

Dist (A, B) == Dist (B, A)

Dist (A, B) + Dist (B, C)> = Dist (A, C)

Algoritmoa
----------

{\displaystyle a} eta {\displaystyle b} karaktere-kateren arteko Levenshtein distantzia, {\displaystyle {\displaystyle \operatorname {lev} \_{a,b}}} matrizearen {\displaystyle {\displaystyle \operatorname {lev} \_{a,b}(|a|,|b|)}} terminoarekin kalkulatzen da, non {\displaystyle \mid a\mid }eta {\displaystyle \mid b\mid } karaktere-kateen luzera diren. Matrizearen osagaiak honela kalkulatzen direla:

{\displaystyle \qquad \operatorname {lev} \_{a,b}(i,j)={\begin{cases}\max(i,j)&{\text{ baldin}}\min(i,j)=0,\\\min {\begin{cases}\operatorname {lev} \_{a,b}(i-1,j)+1\\\operatorname {lev} \_{a,b}(i,j-1)+1\\\operatorname {lev} \_{a,b}(i-1,j-1)+1\_{(a\_{i}\neq b\_{j})}\end{cases}}&{\text{ bestela.}}\end{cases}}}
non:
* {\displaystyle a\_{i}=b\_{j}} denean {\displaystyle 1\_{(a\_{i}\neq b\_{j})}=0}, eta bestela {\displaystyle 1\_{(a\_{i}\neq b\_{j})}=0}
* {\displaystyle {\displaystyle \operatorname {lev} \_{a,b}(i,j)}} zenbakiak distantzia neurtzen du {\displaystyle a} kateko lehen i karaktere eta {\displaystyle b} kateko lehen j karaktereen artean.
* Formulako minimoan hiru aukera daude:
	+ lehen aukerak karaktere baten ezabaketa gertatu dela kontuan hartzen du ({\displaystyle a}-tik {\displaystyle b}-ra),
	+ bigarrenak txertaketa bat gertatu dela suposatzen du,
	+ eta hirugarrenak aztertzen du {\displaystyle a} eta {\displaystyle b} kateetako {\displaystyle i} eta {\displaystyle j} posizioetan sinbolo berdinak azaltzen diren.
		- {\displaystyle a\_{i}=b\_{j}} denean {\displaystyle 1\_{(a\_{i}\neq b\_{j})}=0}, eta bestela {\displaystyle 1\_{(a\_{i}\neq b\_{j})}=0}

Bi adibide:

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
|  |  | e | m | a | n |
|  | 0 | 1 | 2 | 3 | 4 |
| e | 1 | 0 | 1 | 2 | 3 |
| m | 2 | 1 | 0 | 1 | 2 |
| o | 3 | 2 | 1 | 1 | 2 |
| n | 4 | 3 | 2 | 2 | 1 |
| g | 5 | 4 | 3 | 3 | 2 |
| o | 6 | 5 | 4 | 4 | 3 |

 | 

|  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|  |  | S | a | t | u | r | d | a | y |
|  | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| S | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| u | 2 | 1 | 1 | 2 | 2 | 3 | 4 | 5 | 6 |
| n | 3 | 2 | 2 | 2 | 3 | 3 | 4 | 5 | 6 |
| d | 4 | 3 | 3 | 3 | 3 | 4 | 3 | 4 | 5 |
| a | 5 | 4 | 3 | 4 | 4 | 4 | 4 | 3 | 4 |
| y | 6 | 5 | 4 | 4 | 5 | 5 | 5 | 4 | 3 |

 |

### Distantzia kalkulatzeko algoritmo iteratiboa

Algoritmoaren exekuzioan matrize bat kalkulatzen da. Hasieran lehenengo zutabea eta lehenengo errenkada jartzen dira. Ondoren errenkadaz errenkada joaten da zenbakiak ezkerretik eskuinera kalkulatzen. Kasu bakoitzean goian ({\displaystyle {\displaystyle \operatorname {lev} \_{a,b}(i-1,j)}}), ezkerrean ({\displaystyle {\displaystyle \operatorname {lev} \_{a,b}(i,j-1)}}) eta goi-ezkerrean ({\displaystyle {\displaystyle \operatorname {lev} \_{a,b}(i-1,j-1)}}) dauden zenbakiak aztertzen dira, baita zutabeko eta errenkadako letrak ere ({\displaystyle a\_{i}} eta {\displaystyle b\_{j}}).


|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
|  |  | e | m | a | n |
|  | 0 | 1 | 2 | 3 | 4 |
| e | 1 |  |  |  |  |
| m | 2 |  |  |  |  |
| o | 3 |  |  |  |  |
| n | 4 |  |  |  |  |
| g | 5 |  |  |  |  |
| o | 6 |  |  |  |  |

 | 

|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
|  |  | e | m | a | n |
|  | 0 | 1 | 2 | 3 | 4 |
| e | 1 | 0 |  |  |  |
| m | 2 |  |  |  |  |
| o | 3 |  |  |  |  |
| n | 4 |  |  |  |  |
| g | 5 |  |  |  |  |
| o | 6 |  |  |  |  |

 | 

|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
|  |  | e | m | a | n |
|  | 0 | 1 | 2 | 3 | 4 |
| e | 1 | 0 | 1 |  |  |
| m | 2 |  |  |  |  |
| o | 3 |  |  |  |  |
| n | 4 |  |  |  |  |
| g | 5 |  |  |  |  |
| o | 6 |  |  |  |  |

 | 

|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
|  |  | e | m | a | n |
|  | 0 | 1 | 2 | 3 | 4 |
| e | 1 | 0 | 1 | 2 | 3 |
| m | 2 |  |  |  |  |
| o | 3 |  |  |  |  |
| n | 4 |  |  |  |  |
| g | 5 |  |  |  |  |
| o | 6 |  |  |  |  |

 | 

|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
|  |  | e | m | a | n |
|  | 0 | 1 | 2 | 3 | 4 |
| e | 1 | 0 | 1 | 2 | 3 |
| m | 2 | 1 | 0 | 1 | 2 |
| o | 3 |  |  |  |  |
| n | 4 |  |  |  |  |
| g | 5 |  |  |  |  |
| o | 6 |  |  |  |  |

 | 

|  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- |
|  |  | e | m | a | n |
|  | 0 | 1 | 2 | 3 | 4 |
| e | 1 | 0 | 1 | 2 | 3 |
| m | 2 | 1 | 0 | 1 | 2 |
| o | 3 | 2 | 1 | 1 | 2 |
| n | 4 | 3 | 2 | 2 | 1 |
| g | 5 | 4 | 3 | 3 | 2 |
| o | 6 | 5 | 4 | 4 | 3 |

 |

Programazio dinamikoan erabili ohi diren behetik gorako algoritmoetako bat da. (n + 1) × ( m + 1) neurriko matrize bat erabiltzen du, non n eta m zenbakiak kateen luzerak diren. Jarraian erakusten den sasikodezko algoritmoa *LevenshteinDistance* funtzio bat definitzen du. Bi karaktere-kate hartzen ditu (*str1 katea* *lenStr1* luzerakoa eta *str2 katea* *lenStr2* luzerakoa*),* eta horien arteko Levenshtein distantzia kalkulatzen du.Hau da algoritmoa:

```
**int** LevenshteinDistantzia(**char** str1[1..lenStr1], **char** str2[1..lenStr2])
   *// d matrizeak lenStr1+1 errenkada eta lenStr2+1 zutabe*
   **declare** **int** d[0..lenStr1, 0..lenStr2]
   *// i eta j indizeak str1 eta str2* karaktere-kateetan iteratzeko erabiltzen dira.
   **declare** **int** i, j, kostea
 
   **for** i **from** 0 **to** lenStr1
       d[i, 0] := i
   **for** j **from** 0 **to** lenStr2
       d[0, j] := j
 
   **for** i **from** 1 **to** lenStr1
       **for** j **from** 1 **to** lenStr2
           **if** str1[i-1] = str2[j-1] **then** kostea := 0
                                **else** kostea := 1
           d[i, j] := minimum(
                                d[i-1, j] + 1,      *// ezabaketa*
                                d[i, j-1] + 1,      *// txertaketa*
                                d[i-1, j-1] + kostea  *// ordezpena*
                            )
 
   **return** d[lenStr1, lenStr2]
```

Iterazio bakoitzean mantentzen den inbariantea hau da: `str1[1..i]` hasierako segmentutik abiatuta `str2[1..j]` segmentua lortzeko `d[i,j]` eragiketa egin behar dira. Prozesua bukatzean, matrizeko behe-eskuinaldeko posizioan dagoen zenbakia hori izango da `str1` eta `str2`kateen arteko distantzia.

Inplementazioa
--------------

Jarraian, funtzioaren inplementazioa ikus daiteke hainbat programazio-lengoaiatan. Goi mailako lengoaia batzuetan nork berak definitu beharrik gabe erabil daiteke, hala nola php edo MySQLko erabiltzailearen funtzioak.

### C

```
int Levenshtein(char \*s1,char \*s2)
{ int t1,t2,i,j,\*m,kostea,emaitza,zabalera;

// Kalkulatu string-en tamaina
 t1=strlen(s1); t2=strlen(s2);

// Konparatzekorik badagoela egiaztatu
 if (t1==0) return(t2);
 if (t2==0) return(t1);
 zabalera=t1+1;

// malloc-en bidez m matrizerako espazio hartu
 m[i,j] = m[j\*zabalera+i] !!
 m=(int\*)malloc(sizeof(int)\*(t1+1)\*(t2+1));
 if (m==NULL) return(-1); // ERROR!!

// Lehen errenkada eta lehen zutabeari balioak Eliminacion
 for (i=0;i<=t1;i++) m[i]=i;
 for (j=0;j<=t2;j++) m[j\*zabalera]=j;

// Matrizeko gainontzeko osagaietan balioak kalkulatu
 for (i=1;i<=t1;i++) for (j=1;j<=t2;j++)
 { if (s1[i-1]==s2[j-1]) kostea=0; else kostea=1;
 m[j\*zabalera+i]=Minimo(Minimo(m[j\*zabalera+i-1]+1, // ezabaketa 
 m[(j-1)\*zabalera+i]+1), // txertaketa 
 m[(j-1)\*ancho+i-1]+kostea); } // ordezpena 

// Matrizeko azken errenkadako eta azken zutabeko osagaia itzuli
 emaitza=m[t2\*zabalera+t1];
 free(m);
 return(emaitza);
}

```

### C ++

```
#include <string>
#include <vector>
#include <algorithm>

using namespace std;

int levenshtein(const string &s1, const string &s2)
{
 int N1 = s1.size();
 int N2 = s2.size();
 int i, j;
 vector<int> T(N2+1);

 for ( i = 0; i <= N2; i++ )
 T[i] = i;

 for ( i = 0; i < N1; i++ ) 
 {
 T[0] = i+1;
 int corner = i;
 for ( j = 0; j < N2; j++ ) 
 {
 int upper = T[j+1];
 if ( s1[i] == s2[j] )
 T[j+1] = corner;
 else
 T[j+1] = min(T[j], min(upper, corner)) + 1;
 corner = upper;
 }
 }
 return T[N2];
}

```

### C #

```
public int LevenshteinDistantzia(string s, string t, out double portzentajea)
{
 portzentajea = 0;
 
 // d matrizean m+1 errekada eta n+1 zutabe daude
 int costo = 0;
 int m = s.Length;
 int n = t.Length;
 int[,] d = new int[m + 1, n + 1]; 

 // Konparatzekorik badagoela egiaztatu
 if (n == 0) return m;
 if (m == 0) return n;

 // Jarri lehen zutabeko eta lehen erenkadako balioak
 for (int i = 0; i <= m; d[i, 0] = i++) ;
 for (int j = 0; j <= n; d[0, j] = j++) ;
 
 
 /// Matrizeko gainontzeko osagaietan balioak kalkulatu
 /// i zutabe, j errenkada
 for (int i = 1; i <= m; i++)
 {
 // j indizearekin korritu
 for (int j = 1; j <= n; j++)
 { 
 /// posizioan karaktere berdinak badaude pisua 0 da
 /// bestela distantzairako pisua 1 da.
 kostea = (s[i - 1] == t[j - 1]) ? 0 : 1; 
 d[i, j] = System.Math.Min(System.Math.Min(d[i - 1, j] + 1, //ezabaketa
 d[i, j - 1] + 1), //txertaketa 
 d[i - 1, j - 1] + kostea); //ordezpena
 }
 }

 /// Kalkukatu hitz osoan dauden aldaketen portzentajea
 if (s.Length > t.Length)
 portzentajea = ((double)d[m, n] / (double)s.Length);
 else
 portzentajea = ((double)d[m, n] / (double)t.Length); 
 return d[m, n]; 
}

```

### Java

Klase estatiko gisa inplementatua. 

```
public class LevenshteinDistance {
 private static int minimum(int a, int b, int c) {
 return Math.min(a, Math.min(b, c));
 }

 public static int computeLevenshteinDistance(String str1, String str2) {
 return computeLevenshteinDistance(str1.toCharArray(),
 str2.toCharArray());
 }
 private static int computeLevenshteinDistance(char [] str1, char [] str2) {
 int [][]distance = new int[str1.length+1][str2.length+1];

 for(int i=0;i<=str1.length;i++){
 distance[i][0]=i;
 }
 for(int j=0;j<=str2.length;j++){
 distance[0][j]=j;
 }
 for(int i=1;i<=str1.length;i++){
 for(int j=1;j<=str2.length;j++){ 
 distance[i][j]= minimum(distance[i-1][j]+1,
 distance[i][j-1]+1,
 distance[i-1][j-1]+
 ((str1[i-1]==str2[j-1])?0:1));
 }
 }
 return distance[str1.length][str2.length];
 
 }
}

```

### Perl

```
**sub** fastdistance
{
    my $word1 = shift;
    my $word2 = shift;

    **return** 0 if $word1 eq $word2;
    my @d;

    my $len1 = length $word1;
    my $len2 = length $word2;

    $d[0][0] = 0;
    **for** (1.. $len1) {
        $d[$_][0] = $_;
        **return** $_ if $_!=$len1 && substr($word1,$_) eq
            substr($word2,$_);
    }

    **for** (1.. $len2) {
        $d[0][$_] = $_;
        **return** $_ if $_!=$len2 && substr($word1,$_) eq
            substr($word2,$_);
    }

    **for** my $i (1.. $len1) {
        my $w1 = substr($word1,$i-1,1);
        **for** (1.. $len2) {
            $d[$i][$_] = _min($d[$i-1][$_]+1, 
                              $d[$i][$_-1]+1,
                              $d[$i-1][$_-1]+($w1 eq
                                              substr($word2,$_-1,1) ?
                                              0 : 1));
        }
    }
    **return** $d[$len1][$len2];
}

**sub** _min
{
    **return** $_[0] < $_[1]
        ? $_[0] < $_[2] ? $_[0] : $_[2]
        : $_[1] < $_[2] ? $_[1] : $_[2];
}
```

### Python

Programa hau erabiltzen duen aplikazio batean zuzentzaile ortografiko bat sortu egin da.

```
**def** distance(str1, str2):
  d=dict()
  **for** i **in** range(len(str1)+1):
     d[i]=dict()
     d[i][0]=i
  **for** i **in** range(len(str2)+1):
     d[0][i] = i
  **for** i **in** range(1, len(str1)+1):
     **for** j **in** range(1, len(str2)+1):
        d[i][j] = min(d[i][j-1]+1, d[i-1][j]+1, d[i-1][j-1]+(**not** str1[i-1] == str2[j-1]))
  **return** d[len(str1)][len(str2)]
```

### Ruby

```
class String
  def levenshtein(other)
    other = other.to_s
    distance = Array.new(self.size + 1, 0)
    (0..self.size).each do |i|
      distance[i] = Array.new(other.size + 1)
      distance[i][0] = i
    end
    (0..other.size).each do |j|
      distance[0][j] = j
    end

    (1..self.size).each do |i|
      (1..other.size).each do |j|
        distance[i][j] = [distance[i - 1][j] + 1,
                          distance[i][j - 1] + 1,
                          distance[i - 1][j - 1] + ((self[i - 1] == other[j - 1]) ? 0 : 1)].min
      end
    end
    distance[self.size][other.size]
  end
end

puts "eman".levenshtein "emongo" #=> 3

```

### PHP

```
<?php
   $lev = levenshtein($input, $word);
?>

```

### Delphi

```
function LevenshteinDistance(Str1, Str2: String): Integer;
var
 d : array of array of Integer;
 Len1, Len2 : Integer;
 i,j,cost:Integer;
begin
 Len1:=Length(Str1);
 Len2:=Length(Str2);
 SetLength(d,Len1+1);
 for i := Low(d) to High(d) do
 SetLength(d[i],Len2+1);

 for i := 0 to Len1 do
 d[i,0]:=i;

 for j := 0 to Len2 do
 d[0,j]:=j;

 for i:= 1 to Len1 do
 for j:= 1 to Len2 do
 begin
 if Str1[i]=Str2[j] then
 cost:=0
 else
 cost:=1;
 d[i,j]:= Min(d[i-1, j] + 1, // deletion,
 Min(d[i, j-1] + 1, // insertion
 d[i-1, j-1] + cost) // substitution
 );
 end;
 Result:=d[Len1,Len2];
end;

```

### VB. NET

```
 Public Function Levenshtein(ByVal s1 As String, ByVal s2 As String) As Integer
 Dim coste As Integer = 0
 Dim n1 As Integer = s1.Length
 Dim n2 As Integer = s2.Length
 Dim m As Integer(,) = New Integer(n1, n2) {}
 For i As Integer = 0 To n1
 m(i, 0) = i
 Next
 For i As Integer = 0 To n2
 m(0, i) = i
 Next
 For i1 As Integer = 1 To n1
 For i2 As Integer = 1 To n2
 coste = If((s1(i1 - 1) = s2(i2 - 1)), 0, 1)
 m(i1, i2) = Math.Min(Math.Min(m(i1 - 1, i2) + 1, m(i1, i2 - 1) + 1), m(i1 - 1, i2 - 1) + coste)
 Next
 Next
 Return m(n1, n2)
 End Function

```

### ActionScript 3.0

```
public class StringUtils
{
 public static function levenshtein(s1:String, s2:String):int
 { 
 if (s1.length == 0 || s2.length == 0)
 return 0;

 var m:uint = s1.length + 1;
 var n:uint = s2.length + 1;
 var i:uint, j:uint, cost:uint;
 var d:Vector.<Vector.<int>> = new Vector.<Vector.<int>>();
 
 for (i = 0; i < m; i++)
 {
 d[i] = new Vector.<int>();
 for (j = 0; j < n; j++)
 d[i][j] = 0;
 }

 for (i = 0; i < m; d[i][0] = i++) ;
 for (j = 0; j < n; d[0][j] = j++) ;

 for (i = 1; i < m; i++)
 {
 for (j = 1; j < n; j++)
 { 
 cost = (s1.charAt(i - 1) == s2.charAt(j - 1)) ? 0 : 1;
 d[i][j] = Math.min(Math.min(d[i - 1][j] + 1,
 d[i][j - 1] + 1),
 d[i - 1][j - 1] + cost);
 }
 }

 return d[m-1][n-1];
 }
}

```

### ColdFusion

```
<cfscript>
function levDistance(s,t) {
	var d = ArrayNew(2);
	var i = 1;
	var j = 1;
	var s_i = "A";
	var t_j = "A";
	var cost = 0;
	
	var n = len(s)+1;
	var m = len(t)+1;
	
	d[n][m]=0;
	
	if (n is 1) {
		return m;
	}
	
	if (m is 1) {
		return n;
	}
	
	 for (i = 1; i lte n; i=i+1) {
      d[i][1] = i-1;
    }

    for (j = 1; j lte m; j=j+1) {
      d[1][j] = j-1;
    }
	
	for (i = 2; i lte n; i=i+1) {
      s_i = Mid(s,i-1,1);

	  for (j = 2; j lte m; j=j+1) {
      	t_j = Mid(t,j-1,1);

		if (s_i is t_j) {
          cost = 0;
        }
        else {
          cost = 1;
        }
		d[i][j] = min(d[i-1][j]+1, d[i][j-1]+1);
		d[i][j] = min(d[i][j], d[i-1][j-1] + cost);
      }
    }
	
    return d[n][m];
}
</cfscript>

```

### JavaScript

```
/\*
LevenshteinSubminimal(String A, String B) -> {k: Integer, t: String}
 A, hau da erabiltzaileak sartzen duen karaktere-katea
 B, hau da kate alternatiboa izateko hautagaia
 t, hau da Levenshtein distantzia minimizatzen duen karaktere-katea
\*/
function LevenshteinSubminimal(A, B) {
 var a = A.length;
 var b = B.length;

 // A konparatzen da B-ren azpikateekin
 var f = function(s){return Levenshtein(A, s)};

 // A kata B baino luzeagoa bada ez ditugu konparatzen zpikateak
 if(a >= b)
 return {k: f(B), t: B}

 // kasurik txarrena eta mugak
 var m = {k: b+2, t: null}, c1 = a-1, c2 = a+1;
 for(var p = 0; p < b - c1; p++)
 for(var l = c1, c3 = Math.min(c2, b - p); l <= c3; l++) {
 var t = B.substr(p, l), k = f(t);
 // Kasurik onena
 if(m.k >= k)
 m = {k: k, t: t};
 }
 return m;
}

```

### JavaScript (NodeJS)

```
function levenshtein(s1, s2) {
 var l1 = s1.length;
 var l2 = s2.length;
 var d = [];
 var c = 0;
 var a = 0;

 if(l1 == 0)
 return l2;

 if(l2 == 0)
 return l1;

 var d = new Buffer((l1 + 1) \* (l2 + 1));
 a = l1 + 1;

 for(var i = 0; i <= l1; d[i] = i++);
 for(var j = 0; j <= l2; d[j \* a] = j++);

 for(var i = 1; i <= l1; i++) {
 for(var j = 1; j <= l2; j++) {
 if(s1[i - 1] == s2[j - 1])
 c = 0;
 else
 c = 1;
 var r = d[j \* a + i - 1] + 1;
 var s = d[(j - 1) \* a + i] + 1;
 var t = d[(j - 1) \* a + i - 1] + c;

 d[j \* a + i] = Math.min(Math.min(r, s), t);
 }
 }

 return(d[l2 \* a + l1]);
}

```

Aplikazioak
-----------

* ASJP proiektuak Levenshteinen distantzia erabiltzen du hitz zerrenda bat konparatzeko munduko hainbat hizkuntzatan, horien "antzekotasuna" edo "gertutasuna" neurtzeko. Distantzia kalkulatua erabil daiteke munduko hizkuntzen sailkapen filogenetiko tentagarria proposatzeko. .
* Damerau-Levenshtein distantzia zuzentzaile ortografikoek erabiltzen duten Levenshtein distantziaren orokortze bat da, non ondoz ondoko karaktereen arteko trukaketak ere kontuan hartzen diren (tekleatzen sortutako ohiko akats horren pisua jaisteko). Horrela, "eman" eta "eamn" arteko distantzia 1 da, "ma" karaktere-bikotea "am" bihurtu delako.

Ikus, gainera
-------------

* Espazio metrikoa
* Multzokatze hierarkiko
* Zuzentzaile ortografiko
*

Kanpo estekak
-------------

|  |  |
| --- | --- |
| Autoritate kontrola | 
* **Wikimedia proiektuak**
* Wd Datuak: Q496939

 |

* Wd Datuak: Q496939


1. ↑    Etxeberria Uztarroz, Izaskun.  (2016). *Lengoaia eta Sistema Informatikoak SailaInformatika FakultateaAldaera linguistikoen normalizazioainferentzia fonologikoa etamorfologikoa erabiliz..*  UPV/EHU, 221 or..
2. ↑    Alegria, Iñaki; Perez de Viñaspre, Olatz; Sarasola, Kepa.  (2016). *Python programazio-lengoaia: oinarriak eta aplikazioak..*  Udako Euskal Unibertsitatea ISBN 9788484385950. PMC 971786129. (Noiz kontsultatua: 2019-11-08).
3. ↑   **(Ingelesez)** 262588213843476. «Levenshtein substring minimal distance, javascript implementation» *Gist* (Noiz kontsultatua: 2019-11-08).
4. ↑  ASJP - World Language Tree