2014-11-23 7 views
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 

Теперь «крикет» звучит как «criket», но как же «крикет» и «criketgame» одинаковы. Если кто-то объяснит это. это было бы очень полезно.

ответ

1

Ваше использование неверно. Быстрое исследование закодированных строк и длины кода по умолчанию максимальный показывает, что 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")); 

Output (обратите внимание на «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) после первоначальной настройки.

+0

в 8 классе нас учили притчам "внешность обманчива" – jaykio77