String 如何计算两个字符串之间的差?

String 如何计算两个字符串之间的差?,string,pascal,delphi,String,Pascal,Delphi,我想在Delphi中创建一个函数来计算两个字符串的不同级别。如果两个字符串相等(忽略大小写),则应返回0,但如果它们不相等,则应返回不同字符的数目。此函数对于检查拼写非常有用 function GetDiffStringLevel(S1,S2:string):Integer; begin if SameText(S1,S2) then Exit(0); // i want get different chars count end 样本代码: Diff:=GetDiffStringLe

我想在Delphi中创建一个函数来计算两个字符串的不同级别。如果两个字符串相等(忽略大小写),则应返回0,但如果它们不相等,则应返回不同字符的数目。此函数对于检查拼写非常有用

function GetDiffStringLevel(S1,S2:string):Integer;
begin
  if SameText(S1,S2) then Exit(0);
  // i want get different chars count
end
样本代码:

Diff:=GetDiffStringLevel('Hello','Hello');// Diff:=0;
Diff:=GetDiffStringLevel('Hello','2Hello');// Diff:=1;
Diff:=GetDiffStringLevel('Hello','H2ello');// Diff:=1;
Diff:=GetDiffStringLevel('Hello','Hello W');// Diff:=2;
Diff:=GetDiffStringLevel('Hello','World');// Diff:=6; or 5

所需的内容称为(将一个字符串转换为另一个字符串所需的最小编辑次数,其中编辑可以是字符插入、字符删除或字符替换)。维基百科网站有一个伪代码实现

Delphi实现:

function LevenshteinDistance(String1 : String; String2 : String) : Integer;

var
  Length1, Length2      : Integer;
  WorkMatrix            : array of array of Integer;
  I, J                  : Integer;
  Cost                  : Integer;
  Val1, Val2, Val3      : Integer;

begin
String1 := TCharacter.ToUpper (String1);
String2 := TCharacter.ToUpper (String2);
Length1 := Length (String1);
Length2 := Length (String2);
SetLength (WorkMatrix, Length1+1, Length2+1);
for I := 0 to Length1 do
  WorkMatrix [I, 0] := I;
for J := 0 to Length2 do
  WorkMatrix [0, J] := J;
for I := 1 to Length1 do
  for J := 1 to Length2 do
    begin
    if (String1 [I] = String2 [J]) then
      Cost := 0
    else
      Cost := 1;
    Val1 := WorkMatrix [I-1, J] + 1;
    Val2 := WorkMatrix [I, J-1] + 1;
    Val3 := WorkMatrix[I-1, J-1] + Cost;
    if (Val1 < Val2) then
      if (Val1 < Val3) then
        WorkMatrix [I, J] := Val1
      else
        WorkMatrix [I, J] := Val3
    else
      if (Val2 < Val3) then
        WorkMatrix [I, J] := Val2
      else
        WorkMatrix [I, J] := Val3;
    end;
Result := WorkMatrix [Length1, Length2];
end;
函数LevenshteinDistance(String1:String;String2:String):整数;
变量
长度1,长度2:整数;
工作矩阵:整数数组的数组;
一、 J:整数;
成本:整数;
Val1,Val2,Val3:整数;
开始
String1:=TCharacter.ToUpper(String1);
String2:=TCharacter.ToUpper(String2);
长度1:=长度(String1);
长度2:=长度(String2);
设置长度(工作矩阵,长度1+1,长度2+1);
对于I:=0到长度1 do
工作矩阵[I,0]:=I;
对于J:=0到长度2 do
工作矩阵[0,J]:=J;
对于I:=1到长度1 do
对于J:=1到长度2 do
开始
如果(String1[I]=String2[J]),则
成本:=0
其他的
成本:=1;
Val1:=工作矩阵[I-1,J]+1;
Val2:=工作矩阵[I,J-1]+1;
Val3:=工作矩阵[I-1,J-1]+成本;
如果(Val1
快速紧凑的实现

大约是smasher使用普通字符串实现的3倍。 如果其中一个字符串为空,则速度将提高100倍以上

Smasher的函数不区分大小写,这也很有用

function LevenshteinDistance(const s, t: string): integer;inline;
var
  d   : array of array of integer;
  n, m, i, j : integer;
begin
  n := length(s);
  m := length(t);
  if n = 0 then Exit(m);
  if m = 0 then Exit(n);

  SetLength(d, n + 1, m + 1);
  for i := 0 to n do d[i, 0] := i;
  for j := 0 to m do d[0, j] := j;

  for i := 1 to n do
    for j := 1 to m do
      d[i, j] := Min(Min(d[i-1, j]+1, d[i,j-1]+1), d[i-1,j-1]+Integer(s[i] <> t[j]));

  Result := d[n, m];
end;
函数LevenshteinDistance(const s,t:string):整数;内联;
变量
d:整数数组的数组;
n、 m,i,j:整数;
开始
n:=长度(s);
m:=长度(t);
如果n=0,则退出(m);
如果m=0,则退出(n);
设定长度(d,n+1,m+1);
对于i:=0到n做d[i,0]:=i;
对于j:=0到m do d[0,j]:=j;
对于i:=1到n do
对于j:=1到m do
d[i,j]:=Min(Min(d[i-1,j]+1,d[i,j-1]+1),d[i-1,j-1]+整数(s[i]t[j]);
结果:=d[n,m];
结束;

注意:
inline
指令将我的计算机上的执行时间减少到70%以下,但仅适用于win32目标平台。如果编译为64位(Delphi XE2),内联实际上会让它慢一点。

另请参见:。@MajidTaheri:您要求一个函数来计算两个单词之间的差异,而Smasher的函数就是您问题的答案。您在问题中从未说过如何准确使用该函数。@MajidTaheri,您可以尝试实现
Levenshtein Distance
@LU RD,EditDistance函数更好。如果两个字符串中的一个为空,您可以退出该函数。当有一个空字符串时,这要快得多,而且在其他方面花费也不多。只需添加:
如果长度1=0,则退出(长度2);如果长度2=0,则退出(长度1)