トライはスペースを節約しますが、どうですか?

I am confused as to how the Trie implementation saves space & stores data in most compact form!

If you look at the tree below. When you store a character at any node, you also need to store a reference to that & thus for each character of the string you need to store its reference. Ok we saved some space when a common character arrived but we lost more space in storing a reference to that character node.

したがって、このツリー自体を維持するための構造上のオーバーヘッドはありませんか?この代わりにTreeMapを使用した場合、辞書を実装すると、文字列が1つの部分に保存されるため、より多くのスペースを節約できる可能性があります。したがって、参照を格納するスペースが無駄にならないでしょうか?

enter image description here

12
ノードが16バイトを取りますが、16文字を超える文字列(Javaの場合は8文字)で再利用されると、スペースが節約されます。それは単にあなたが浪費しているより多くのスペースを節約するかどうかの問題です。あなたの例の青い数字が繰り返し回数であると仮定すると、節約は単純な文字列の配列に比べて無駄なスペースよりも大きくなることが分かります。しかし、この場合、リピート数で完全な文字列を格納する方が良いでしょう。
追加された 著者 han,

5 答え

トライを使用する際にスペースを節約するために、圧縮トライ(パトリシアトライ1つのノードが複数の文字を表すことができます。

コンピュータサイエンスでは、基数木(patricia trieまたは基数trie)   空間最適化されたトライデータ構造であり、各ノードは、   子供はその子供と合併される。その結果、すべての内部ノード   少なくとも2人の子供がいます。通常の試行とは異なり、エッジは   文字のシーケンスと単一文字でラベル付けされています。   これにより、小さなセットではより効率的になります(特に   文字列が長い)、長い接頭辞を共有する文字列のセットの場合。

基数ツリーの例:

radix tree or patricia trie

トライは通常、一連の文字列のプレフィックスマッチングのための効率的なデータ構造として使用されることに注意してください。トライは、キーが文字列である連想配列(ハッシュテーブルのような)としても使用できます。

14
追加された
私はPatricia Trieの実装を見ましたが、それは彼らの主張に従って、Guava&Apache Commonsのような一般的な図書館の一部ですか?私はGuava/apacheコモンズコレクションでその実装を理解できませんでした
追加された 著者 Rajat Gupta,
冷やす解明してくれてありがとう!
追加された 著者 Rajat Gupta,
@ダビデは数値が値を示していますか?
追加された 著者 Pacerier,
@Marcos Guavaにはトライ実装はありませんが、最終的に起こる可能性があるため、長時間実行すると問題が発生します。
追加された 著者 ColinD,
@DavidHu:私はPatricia Trie問題についても取り組んでいます。ここを参照してください。そして、現在私は立ち往生しています。あなたが私をそこで助けることができるなら、それは大きな助けになるでしょう..ありがとう..
追加された 著者 user2467545,

木が表現する言葉がたくさんあるときは、スペースが節約されます。多くの単語が木の中で同じ道を共有するので、あなたが持っている単語が多いほど、保存するスペースが増えます。

しかし、スペースを節約したい場合は、より良いデータ構造があります。トライは、 DAWG(directed acyclic word graph)のようにスペースを節約しません。構造全体にわたって共通ノードを共有しますが、trieはノードを共有しません。 rel="nofollow noreferrer"> wikiのエントリでは、このような詳細について説明していますので、一見してみてください。

TrieとDAWGの違いは(グラフで)次のとおりです。

enter image description here

Trie(左)とDAWG(右)に格納されている文字列「tap」、「tap」、「top」、「tops」は、EOFは単語の終わりを表します。

左側のツリーはトライ、右側のツリーはDAWGです。それらを比較して、DAWGがどのようにスペースを徹底的に節約するかを見てください。トライには同じ文字/サブワードを表すノードが重複していますが、DAWGには各文字/サブワードごとに1つのノードがあります。

6
追加された
@Pacerier:あなたは何回ポインターを支払っていますか?一度あなたがそれを支払うと、あなたが望むのと同じくらい多くの繰り返しを使用することができます。
追加された 著者 Nawaz,
これは私が理解していないものです。私たちが保存するキャラクターごとに、私たちはポインターの価格を支払っています。そうではありませんか?
追加された 著者 Pacerier,

メモリ内の安価なスペースではなく、ファイル内や通信リンク上の貴重なスペースです。そのトライを構築するアルゴリズムでは、「10」を左右3ビットで送信できます。 24ビットの「10」は圧縮されていないため、貴重なディスク容量や転送帯域幅を大幅に節約できます。

5
追加された
それは本当に大きな利点です!
追加された 著者 Rajat Gupta,
したがって、データを転送する必要はないが、約10,000の名前の電話名ディレクトリの検索候補を得るための効率的でスペース効率の良いソリューションのためには、TreeMapよりもTrieを使用することをお勧めしますか?
追加された 著者 Rajat Gupta,

すべてのバイトが効率的に割り当てられる理想的なマシン上に、スペースを節約できることが推測できます。しかし、実際のマシンでは、整列したメモリブロック(Javaでは8バイト、C ++では16バイト)を割り当てるため、スペースを節約できません。

Javaの文字列とコレクションは、オーバーヘッドの割合が比較的高く、パーセンテージの差は非常に小さくなります。

あなたの構造が非常に大きい場合を除き、タイムアウトの価値は、最も簡単で最も標準的で最も簡単なコレクションを維持することをはるかに重要とするメモリコストを重くします。例えばあなたの時間は、あなたが保存しようとしているメモリの価値の1000倍以上に相当する価値があります。

例えばトライを使用してそれぞれ16バイトを保存できる10000の名前があるとします。 (これは時間をかけずに証明できると仮定します)これは今日の価格で0.1セントの価値がある16 KBに相当します。あなたの時間があなたの会社に1時間に30ドルかかる場合、テストされたコードの1行を書くコストは$ 1かもしれません。

あなたが16KBを節約するために長い目で瞬きを考えると、それはPCの価値があるとは思えません。 (モバイルデバイスは異なるストーリーですが、同じ議論がIMHOを適用します)

EDIT: You have inspired me to add an update http://vanillajava.blogspot.com/2011/11/ever-decreasing-cost-of-main-memory.html

2
追加された
何千人も何百万人もの消費者に配備されているライブラリを書く場合、その0.2セントには倍数があり、使用量によって課金されるサーバーに配備されると、0.2セントにはもう1つの倍数があります。 "パフォーマンスは問題ではありません"という解決策ではなく、イデオロギーです。
追加された 著者 Ajax,
私は、たとえ少し時間がかかっても、最もパフォーマンスの高いソリューションを常に選択する、より楽観的なアプローチを好みます。最良の結果を得るためにどのような方法を使用するのかをベンチマークし、どのような状況であるかを知っている限り、ボトルネックがどこにあるかを常に知り、習慣からそれらを避けることができます。誰かがArrayList.add(0、item)を使うのを見るたびに、私はLinkedListを見るためにコメントを残します。あなたのツールがフードの中で何をしているのかわからない場合、間違いを犯してアプリケーションが遅くなる。サーバーコストの支払いは1つのことですが、潜在的なユーザーの最初の印象は貴重です。
追加された 著者 Ajax,
トライはより速くなり、スペースを節約できます。 15Kエントリでは、メモリとCPUの0.2セントを節約できます。あなたが道路の反対側の0.2セントになることを見たなら、それを拾うために交差するでしょうか?私はあなたの時間の約2分の1を取る場合、私はこれを行うだけです。 TreeMapは、組み込みのテスト済みの文書であり、コードをサポートしなければならない人には理解されているので、メモリーを消費するよりはるかに時間がかかります(多くのデバイスを使用していない限り、メモリは制限されません)
追加された 著者 Peter Lawrey,
100万台のマシンに0.2セントを貯めれば合計2000ドルです。これは、数日または1週間に費やす価値があります。 100K台のマシンであれば、数時間でも1日でも見ています。それがわずか10Kのマシンなら、あなたは数分見ている。それが1000台以下のマシンならば、あなたはそれについて心配する時間を無駄にするかもしれません。スケールは重要であり、ほとんどのプロジェクトは十分なマシンに配備されないため、少量のリソースを心配することは良い考えです。
追加された 著者 Peter Lawrey,

グアバは実際に各レベルにキーを格納することができますが、実現するポイントは、ノードへのパスがそのノードのキーを完全に定義するため、キーを実際に格納する必要はありません。実際に各ノードに格納する必要があるのは、これがリーフノードかどうかを示す単一のブール値だけです。

他の構造と同様、試行は特定の種類のデータを保存するのに優れています。具体的には、共通のルートを共有する文字列を格納するときに最適です。たとえば、フルパスのディレクトリリストを保存すると考えてください。

1
追加された