我在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"是相同的。如果有人会解释这个。这将是非常有帮助的。
答案 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)
。