T minimum(T)(T[] all ...) in { assert(all.length > 0); } out(result) { foreach (t; all) assert(result <= t); } body { T ret = all[0]; foreach (t; all) if (t < ret) ret = t; return ret; } struct array2d(T) { private int w; private T[] data; public this(int w, int h) { this.data = new T[w*h]; this.w = w; } public T get(int x, int y) { return data[x+y*w]; } public void set(int x, int y, T t) { data[x+y*w] = t; } } int LevenshteinDistance(string s, string t) { const int m = s.length; const int n = t.length; // d is a table with m+1 rows and n+1 columns array2d!(int) d = array2d!(int)(m+1,n+1); foreach (i; 0..m+1) d.set(i, 0, i); // deletion foreach (j; 0..n+1) d.set(0, j, j); // insertion int k = 0; foreach (j; 1..n+1) { foreach (i; 1..m+1) { int cost = 1; if (s[i-1] == t[j-1]) cost = 0; k = minimum( d.get(i-1, j) + 1, // deletion d.get(i, j-1) + 1, // insertion d.get(i-1, j-1) + cost // substitution ); // transposition ab -> ba if (i > 1 && j > 1 && s[i-1] == t[j-2] && s[i-2] == t[j-1]) k = minimum( k, d.get(i-2, j-2) + cost // transposition ); d.set(i, j, k); } } return k;//d.get(m,n); } unittest { assert(LevenshteinDistance("hello", "hello") == 0);//nop assert(LevenshteinDistance("hello", "helo") == 1);//del assert(LevenshteinDistance("hello", "heello") == 1);//ins assert(LevenshteinDistance("hello", "hallo") == 1);//change assert(LevenshteinDistance("hello", "hlelo") == 1);//transp assert(LevenshteinDistance("hello", "hlelq") == 2); } import std.stdio; void main(string[] args) { writefln("%s", LevenshteinDistance(args[1], args[2])); }