web-dev-qa-db-ja.com

辞書を実装するのに最適なデータ構造ですか?

辞書のすべての単語を保存するのに最適なデータ構造は何でしょうか?考えられる最善の方法は、HashMapを使用することで、これはHashTableにマップされます。基本的に、最初の文字に応じて、関連するHashTableを取得し、これを使用して、その文字から始まる単語を追加できます。次に、文字列に基づいて適切なハッシュ関数を選択します。

より良いアプローチはありますか?

63
Jatin

目的に応じて、多くの優れたデータ構造があります。

単語を保存し、「この単語はここにあるのかどうか」と尋ねるだけなら、他の派手な機構のない標準のハッシュテーブルは合理的なアプローチです。そのWordが事前にリストが修正されている場合は、 完全なハッシュテーブル を使用して、優れたパフォーマンスとスペース使用量を取得することを検討してください。

高速ルックアップをサポートしているときに特定のプレフィックスが存在するかどうかを確認したい場合は、 trie が適切なオプションですが、少しスペースが効率的ではありません。また、高速な挿入または削除もサポートしています。また、アルファベット順の反復が可能になりますが、ハッシュは提供しません。これは基本的に回答で説明した構造ですが、ユースケースによっては、試行の他の表現の方が優れている場合があります。

上記に加えて、Wordリストが固定されているという事実を知っている場合、本質的には [〜#〜] dawg [〜#〜] (有向非周期Wordグラフ)の使用を検討してください。言語の最小状態のDFA。トライよりもかなりコンパクトですが、同じ操作の多くをサポートしています。

トライのような振る舞いをしたいが、大きなスペースのペナルティを払いたくない場合、 基数ツリー と同様に、 三分探索木 も実行可能なオプションです。これらは非常に異なる構造ですが、異なる状況でトライよりもはるかに優れている可能性があります。

スペースが問題であるが、トライが必要な場合は、 succinct trie 表現を調べてください。これにより、ルックアップは遅くなりますが、理論的に最適なスペース使用量になります。このリンクでは、膨大な量のデータを簡単に送信する方法としてJavaScriptでどのように使用されているかについて説明しています。代替のコンパクトな表現は double-array trie ですが、確かに私はそれについてほとんど知りませんが。

他の単語に類似した単語を見つける必要があるスペルチェックなどの操作に辞書を使用する場合、 BK-tree は考慮すべき優れたデータ構造です。

お役に立てれば!

138
templatetypedef