随笔 - 2146  文章 - 97 评论 - 11767 trackbacks - 253

//先糊涂一下
var
  b: Boolean;
begin
  b := AnsiResemblesText('abc','apc');
  ShowMessage(BoolToStr(b)); {True}

  b := AnsiResemblesText('abc','agc');
  ShowMessage(BoolToStr(b)); {False}

  b := AnsiResemblesText('abc','aac');
  ShowMessage(BoolToStr(b)); {False}

{结论: 它只认为第一对是相似的; 它到底根据什么判断的?}
end;

//我追根求源, 找到了这个函数: Soundex var s: string; begin s := Soundex('abc'); ShowMessage(s); {A120} s := Soundex('apc'); ShowMessage(s); {A120} s := Soundex('agc'); ShowMessage(s); {A200} s := Soundex('aac'); ShowMessage(s); {A200} {结论: AnsiResemblesText 是根据 Soundex 生成的另一个字符码来比对的} end;
//首先 Soundex 把第一个字母读出, 不区分大小写, 但用大写表示 var s: string; begin s := Soundex('xabc'); ShowMessage(s); {X120} s := Soundex('Yabc'); ShowMessage(s); {Y120} s := Soundex('zabc'); ShowMessage(s); {Z120} {结论: 如果第一个字母不同, 是绝对不会相似的} end;
//从第2-4个字母, Soundex 为他们分别读出一个值: // h w -1 // a e i o u y 0 // b f p v 1 // c g j k q s x z 2 // d t 3 // l 4 // m n 5 // r 6 // //不过最后把 -1 也认做 0 了; 如果字母缺失也会认做 0 begin ShowMessage(Soundex('Aa')); {A000} ShowMessage(Soundex('Ae')); {A000} ShowMessage(Soundex('Ai')); {A000} ShowMessage(Soundex('Ao')); {A000} ShowMessage(Soundex('Au')); {A000} ShowMessage(Soundex('Ay')); {A000} ShowMessage(Soundex('Ah')); {A000} ShowMessage(Soundex('Aw')); {A000} ShowMessage(Soundex('Ab')); {A100} ShowMessage(Soundex('Af')); {A100} ShowMessage(Soundex('Ap')); {A100} ShowMessage(Soundex('Av')); {A100} ShowMessage(Soundex('Ac')); {A200} ShowMessage(Soundex('Ag')); {A200} ShowMessage(Soundex('Aj')); {A200} ShowMessage(Soundex('Ak')); {A200} ShowMessage(Soundex('Aq')); {A200} ShowMessage(Soundex('As')); {A200} ShowMessage(Soundex('Ax')); {A200} ShowMessage(Soundex('Az')); {A200} ShowMessage(Soundex('Ad')); {A300} ShowMessage(Soundex('At')); {A300} ShowMessage(Soundex('AL')); {A400} ShowMessage(Soundex('Am')); {A500} ShowMessage(Soundex('An')); {A500} ShowMessage(Soundex('Ar')); {A600} {结论: 以上只要值是一样的, 最后的结果当然是相似; 它好像是根据发音分类的} end;
//从第2-4个字母如果不重复, 道理也就一样了 var b: Boolean; begin {b 的编码是 1} ShowMessage(Soundex('Ab')); {A100} ShowMessage(Soundex('Abb')); {A100} ShowMessage(Soundex('Abbb')); {A100} {r 的编码是 6} ShowMessage(Soundex('Arbb')); {A610} ShowMessage(Soundex('Abbr')); {A160} ShowMessage(Soundex('Abrb')); {A161} {测试} b := AnsiResemblesText('Ab','Abbb'); ShowMessage(BoolToStr(b)); {返回 -1, 也就是 True; 它认为 Ab 与 Abbb 是相似的} {结论: 如果字母连续重复, 后面相同的字母将被忽略, 缺位补 0} end;
//如果没有重复, 从第 4 个字母以后就不再计算了 var b: Boolean; begin ShowMessage(Soundex('Abcd')); {A123} ShowMessage(Soundex('Abcdbcdbcd')); {A123} {测试} b := AnsiResemblesText('Abcd','Abcdbcdbcd'); ShowMessage(BoolToStr(b)); {True} {如果有重复} ShowMessage(Soundex('Abbbcd')); {A123} ShowMessage(Soundex('Abcd')); {A123} {测试} b := AnsiResemblesText('Abbbcd','Abcd'); ShowMessage(BoolToStr(b)); {True} {结论: 它只给前 4 个字母编码, 之后的忽略; 如果第 2-4 个字母有连续的重复, 被忽略掉的字母会用后面的补齐. } end;
//其实 Soundex 还有一个可选参数, 它的默认值是 4 var b: Boolean; begin ShowMessage(Soundex('Abcd', 6)); {A12300} ShowMessage(Soundex('Abcdbcd', 6)); {A12312} {测试} b := AnsiResemblesProc('Abcdbcd','Abcdbcd'); ShowMessage(BoolToStr(b)); {True} {结论: AnsiResemblesText 函数在使用 Soundex 时, 只是使用了默认值 4; 也就是这个问题在 AnsiResemblesText 中并不存在; 如果需要更复杂的比对, 直接调用 Soundex 函数就是了. 另外, 还有一个函数 AnsiResemblesProc 和 AnsiResemblesText 是一么一样的; 不过是后者调用了前者罢了, 无他! } end;
//一旦明白了, 就没有进行更多测试; 如发现不对, 万望告诉 万一 一声!
posted on 2007-12-28 22:12  万一  阅读(...)  评论(...编辑  收藏