20

I'm posting this in the spirit of answering your own questions.

The question I had was: How can I implement the Levenshtein algorithm for calculating edit-distance between two strings, as described here, in Delphi?

Just a note on performance: This thing is very fast. On my desktop (2.33 Ghz dual-core, 2GB ram, WinXP), I can run through an array of 100K strings in less than one second.

JosephStyons
  • 57,317
  • 63
  • 160
  • 234
  • 11
    It has been encouraged by Jeff to answer ones own questions. This is not only a query platform but a platform to find answers. Who they are coming from - who cares. Well done. – Ralph M. Rickenbach Sep 11 '08 at 05:18

1 Answers1

18
function EditDistance(s, t: string): integer;
var
  d : array of array of integer;
  i,j,cost : integer;
begin
  {
  Compute the edit-distance between two strings.
  Algorithm and description may be found at either of these two links:
  http://en.wikipedia.org/wiki/Levenshtein_distance
  http://www.google.com/search?q=Levenshtein+distance
  }

  //initialize our cost array
  SetLength(d,Length(s)+1);
  for i := Low(d) to High(d) do begin
    SetLength(d[i],Length(t)+1);
  end;

  for i := Low(d) to High(d) do begin
    d[i,0] := i;
    for j := Low(d[i]) to High(d[i]) do begin
      d[0,j] := j;
    end;
  end;

  //store our costs in a 2-d grid  
  for i := Low(d)+1 to High(d) do begin
    for j := Low(d[i])+1 to High(d[i]) do begin
      if s[i] = t[j] then begin
        cost := 0;
      end
      else begin
        cost := 1;
      end;

      //to use "Min", add "Math" to your uses clause!
      d[i,j] := Min(Min(
                 d[i-1,j]+1,      //deletion
                 d[i,j-1]+1),     //insertion
                 d[i-1,j-1]+cost  //substitution
                 );
    end;  //for j
  end;  //for i

  //now that we've stored the costs, return the final one
  Result := d[Length(s),Length(t)];

  //dynamic arrays are reference counted.
  //no need to deallocate them
end;
JosephStyons
  • 57,317
  • 63
  • 160
  • 234
  • 1
    The cleanup part is not needed, and might even hurt performance. the dynamic array will be de-allocated by Delphi when the function exits. – kobik May 14 '12 at 10:20
  • Thanks @kobik! I forgot that dynamic arrays are reference counted and are deallocated for us. Code has been adjusted accordingly. – JosephStyons May 14 '12 at 14:21
  • 4
    [Wouter van Nifterick](http://stackoverflow.com/users/38813/wouter-van-nifterick) made a more optimized function [here](http://stackoverflow.com/a/10593797/576719). – LU RD May 15 '12 at 06:14