1

我正在对 Java 中的不同单词使用语音匹配。我使用了 Soundex,但它太粗糙了。我切换到 Metaphone 并意识到它更好。但是,当我严格测试它时。我发现了奇怪的行为。我想问一下变音器是这样工作的,还是我用错了。在以下示例中,它的工作正常:-

Metaphone meta = new Metaphone();
if (meta.isMetaphoneEqual("cricket","criket")) System.out.prinlnt("Match 1");
if (meta.isMetaphoneEqual("cricket","criketgame")) System.out.prinlnt("Match 2");

这将打印

  Match 1
  Mathc 2

现在“板球”听起来确实像“板球”,但“板球”和“板球比赛”怎么会是一样的。如果有人会解释这一点。这会有很大帮助。

4

1 回答 1

2

你的用法有点不正确。对编码字符串和默认最大代码长度的快速调查表明它是 4,这会截断较长的“criketgame”的结尾:

System.out.println(meta.getMaxCodeLen());
System.out.println(meta.encode("cricket"));
System.out.println(meta.encode("criket"));
System.out.println(meta.encode("criketgame"));

输出(注意“criketgame”从“KRKTKM”截断为“KRKT”,与“cricket”匹配):

4
韩国电信
韩国电信
韩国电信


解决方案:将最大代码长度设置为适合您的应用程序和预期输入的值。例如:

meta.setMaxCodeLen(8);
System.out.println(meta.encode("cricket"));
System.out.println(meta.encode("criket"));
System.out.println(meta.encode("criketgame"));

现在输出:

韩国电信
韩国电信
KRKTKM

现在您的原始测试给出了预期的结果:

Metaphone meta = new Metaphone();
meta.setMaxCodeLen(8);
System.out.println(meta.isMetaphoneEqual("cricket","criket"));
System.out.println(meta.isMetaphoneEqual("cricket","criketgame"));

印刷:

真的
错误的

顺便说一句,您可能还想尝试一下DoubleMetaphone,这是算法的改进版本。


顺便说一句,请注意文档中有关线程安全的警告:

实例字段maxCodeLen是可变的但不是易失的,并且访问不同步。如果类的实例在线程之间共享,则调用者需要确保使用适当的同步来确保线程之间值的安全发布,并且不得setMaxCodeLen(int)在初始设置后调用。

于 2014-11-23T20:41:50.270 回答