1

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

"cricket" は "cricket" のように聞こえますが、なぜ "cricket" と "cricketgame" は同じなのでしょうか。誰かがこれを説明するなら。それは大いに役立つでしょう。

4

1 に答える 1

2

あなたの使い方は少し間違っています。エンコードされた文字列とデフォルトの最大コード長を簡単に調べると、それが 4 であることがわかります。これは、より長い「クリケット ゲーム」の終わりを切り捨てます。

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

出力 (「cricketgame」は「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)、初期セットアップ後に呼び出してはなりません。

于 2014-11-23T20:41:50.270 に答える