Metaphone算法出乎意料的结果

时间:2014-11-23 20:20:25

标签: java apache-commons-codec metaphone

我在Java中使用不同单词的语音匹配。我使用Soundex,但它太粗糙了。我转向Metaphone并意识到它更好。但是,当我严格测试它。我发现了奇怪的行为。我要问这是因为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

现在"板球"听起来像" criket"但是怎么来"板球"和" criketgame"是相同的。如果有人会解释这个。这将是非常有帮助的。

1 个答案:

答案 0 :(得分: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”,与“板球”匹配):

4
KRKT
KRKT
KRKT

<小时/> 解决方案:将最大代码长度设置为适合您的应用程序和预期输入的内容。例如:

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

现在输出:

KRKT
KRKT
KRKTKM

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

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

印刷:

true
false

另外,您可能还想尝试DoubleMetaphone,这是该算法的改进版本。


顺便提一下,请注意the documentation关于线程安全的警告:

  

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