Неожиданные результаты от алгоритма Metaphone

Я использую фонетическое соответствие для разных слов в Java. Я использовал Soundex, но он слишком грубый. Я переключился на Метафон и понял, что это лучше. Однако, когда я строго проверил это. я обнаружил странное поведение. я должен был спросить, так ли работает метафон, или я использую его неправильно. В следующем примере это прекрасно работает:

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

Теперь "крикет" звучит как "крикет", но почему "крикет" и "игра в крикет" совпадают. Если кто-то объяснит это. это было бы очень полезно.

1 ответ

Решение

Ваше использование немного неверно. Быстрое исследование закодированных строк и максимальной длины кода по умолчанию показывает, что оно равно 4, что обрезает конец более длинной "игры в крикет":

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
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"));

Печать:

правда
ложный

Кроме того, вы также можете поэкспериментировать сDoubleMetaphone, который является улучшенной версией алгоритма.


Кстати, обратите внимание на предостережение в документации по безопасности потоков:

Поле экземпляра maxCodeLen изменчив, но не является изменчивым, и доступы не синхронизированы. Если экземпляр класса совместно используется потоками, вызывающая сторона должна убедиться, что используется подходящая синхронизация для безопасной публикации значения между потоками, и не должна вызывать setMaxCodeLen(int) после начальной настройки.

Другие вопросы по тегам