トリプル(Trie)
トリプル(Trie)
trieとは?
trayはCSのブラウズツリーです.文字列は通常キーです.
バイナリ・ナビゲーション・ツリーとは異なり、ツリー内の任意のノードは、そのノード自体に関連する鍵を保存しません.
逆に、ノードはツリー内の位置で関連するキーを定義します.
すなわち,キー値は資料構造全体に分散する.ノードのすべてのサブノードは、ノードに関連付けられた文字列の共通接頭辞を共有します.
ルート(head)は空の文字列に関連付けられています.
一部の内部ノードは鍵に対応する可能性があるが、通常、鍵を端末に関連付ける傾向がある.したがって、すべてのノードが鍵に関連付けられているわけではありません.
検索文字列に効率的です。
3つの例
各文字列のアルファベットはノードの値になります.
一部のノードにはwordの要素に関する情報が含まれています.これは、ノードにナビゲートすると、ナビゲーション中にアルファベットからなる単語が現在のtrieに存在することを意味します.
例えば、「韓国」では、「a」だけが「韓国」の情報を持っている.
「korean」には「n」に「korean」という情報があります.
これにより,Trightは接頭辞が重複する単語を効率的に管理することができ,ある単語を検索するクエリでは,時間的複雑度はO(N)O(N)O(N)(N=単語の長さを検索する)ことによって見つけることができる.
時間の複雑なグラフィックでは優れていますが、各アルファベット、各順序に作成するノードがたくさんあるので、メモリが消費されます.
質問する
14425号:文字列セット
概要
実際には、上記の問題もハッシュによって解決することができる.
しかし、メモリ制限が1536 MBであることを考慮すると、フラッシュの練習には良い問題だと思います.
3階層アーキテクチャ
ノードクラス
class Node:
def __init__(self, key, data=None):
self.key = key
self.data = data
self.children = {}
trieのコンポーネントノードに関するクラスです.
key(アルファベット)、data(単語は存在しない)、children(現在のノードのサブノード)から構成されます.
dataにより,現在のノードのkeyを最後のスペルとする単語があるか否かを判断できる.
childrenは、Trieクラスメソッドでノードを再帰的にナビゲートするために使用される.
Trueクラス
class Trie:
def __init__(self):
self.head = Node(None)
triclassの作成者はkey=Noneノードです.
そしてこのノードはTreeのhead,すなわちルートノードとなる.
insert
def insert(self, word):
cur_node = self.head
for char in word:
if char not in cur_node.children:
cur_node.children[char] = Node(char)
cur_node = cur_node.children[char]
cur_node.data = word
trieに単語を挿入する方法.
wordをparameterとして受け入れ,wordのスペルをノードオブジェクトごとに生成しtrieに入れる.
trieを入れることはheadからサブノード(children)に順次割り当てることを意味する.
search
def search(self, word):
cur_node = self.head
for char in word:
if char in cur_node.children:
cur_node = cur_node.children[char]
else:
return False
検索する単語がtrieに存在するかどうかを確認する方法.
ここにいるよデータを使用します.
ヘッダーから順にサブノードをチェックし、スペルが一致するノードがある場合は、同じ検索を再帰的に繰り返す.
スペルがtrieにない場合、またはすべてのスペルがtrieにあり、データがない場合はfalseを返します.
start_with
def start_with(self, prefix):
cur_node = self.head
for char in prefix:
if char in cur_node.children:
cur_node = cur_node.children[char]
else:
return None
words = []
next_node = []
if cur_node.data: #app
words.append(cur_node.data)
next_node.extend(list(cur_node.children.values()))
if len(next_node) == 0: return words
cur_node = list(next_node)
next_node = []
while True:
for node in cur_node:
if node.data:
words.append(node.data)
next_node.extend(list(node.children.values()))
if len(next_node) == 0: return words
cur_node = list(next_node)
next_node = []
検索する文字列を接頭辞として使用する単語をすべて返す方法.
headからchildをチェックし、prefixのアルファベット全体がtrieに存在するかどうかを決定します.
存在しない場合はNoneを返します.
prefixの最後のアルファベットの後にすべてのchildをナビゲートし、ノードにデータがあることを確認する必要があります.
単語はwordsに追加され,現在のノードのサブノードをnext nodeに保存し,cur nodeをnext nodeに更新する.その後更新されるcur nodeについても同じ操作を繰り返します.
動作実行方式はBFSと同様である.
まずすべてのchildをチェックし、次のwhile文で作業します.
cur nodeが更新されない場合は、保存したwordを返します.
質問回答コード
import sys
In = lambda: sys.stdin.readline().rstrip()
MIS = lambda: map(int, In().split())
class Node:
def __init__(self, key, data=None):
self.key = key
self.data = data
self.children = {}
class Trie:
def __init__(self):
self.head = Node(None)
def insert(self, word):
cur_node = self.head
for char in word:
if char not in cur_node.children:
cur_node.children[char] = Node(char)
cur_node = cur_node.children[char]
cur_node.data = word
def search(self, word):
cur_node = self.head
for char in word:
if char in cur_node.children:
cur_node = cur_node.children[char]
else:
return False
if cur_node.data:
return True
else:
return False
def start_with(self, prefix):
cur_node = self.head
for char in prefix:
if char in cur_node.children:
cur_node = cur_node.children[char]
else:
return None
words = []
next_node = []
if cur_node.data: #app
words.append(cur_node.data)
next_node.extend(list(cur_node.children.values()))
if len(next_node) == 0: return words
cur_node = list(next_node)
next_node = []
while True:
for node in cur_node:
if node.data:
words.append(node.data)
next_node.extend(list(node.children.values()))
if len(next_node) == 0: return words
cur_node = list(next_node)
next_node = []
if __name__ == "__main__":
N, M = MIS()
trie = Trie()
for _ in range(N):
trie.insert(In())
ans = 0
for _ in range(M):
if trie.search(In()):
ans += 1
print(ans)
Reference
この問題について(トリプル(Trie)), 我々は、より多くの情報をここで見つけました
https://velog.io/@seilk/트라이Trie
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
class Node:
def __init__(self, key, data=None):
self.key = key
self.data = data
self.children = {}
class Trie:
def __init__(self):
self.head = Node(None)
def insert(self, word):
cur_node = self.head
for char in word:
if char not in cur_node.children:
cur_node.children[char] = Node(char)
cur_node = cur_node.children[char]
cur_node.data = word
def search(self, word):
cur_node = self.head
for char in word:
if char in cur_node.children:
cur_node = cur_node.children[char]
else:
return False
def start_with(self, prefix):
cur_node = self.head
for char in prefix:
if char in cur_node.children:
cur_node = cur_node.children[char]
else:
return None
words = []
next_node = []
if cur_node.data: #app
words.append(cur_node.data)
next_node.extend(list(cur_node.children.values()))
if len(next_node) == 0: return words
cur_node = list(next_node)
next_node = []
while True:
for node in cur_node:
if node.data:
words.append(node.data)
next_node.extend(list(node.children.values()))
if len(next_node) == 0: return words
cur_node = list(next_node)
next_node = []
import sys
In = lambda: sys.stdin.readline().rstrip()
MIS = lambda: map(int, In().split())
class Node:
def __init__(self, key, data=None):
self.key = key
self.data = data
self.children = {}
class Trie:
def __init__(self):
self.head = Node(None)
def insert(self, word):
cur_node = self.head
for char in word:
if char not in cur_node.children:
cur_node.children[char] = Node(char)
cur_node = cur_node.children[char]
cur_node.data = word
def search(self, word):
cur_node = self.head
for char in word:
if char in cur_node.children:
cur_node = cur_node.children[char]
else:
return False
if cur_node.data:
return True
else:
return False
def start_with(self, prefix):
cur_node = self.head
for char in prefix:
if char in cur_node.children:
cur_node = cur_node.children[char]
else:
return None
words = []
next_node = []
if cur_node.data: #app
words.append(cur_node.data)
next_node.extend(list(cur_node.children.values()))
if len(next_node) == 0: return words
cur_node = list(next_node)
next_node = []
while True:
for node in cur_node:
if node.data:
words.append(node.data)
next_node.extend(list(node.children.values()))
if len(next_node) == 0: return words
cur_node = list(next_node)
next_node = []
if __name__ == "__main__":
N, M = MIS()
trie = Trie()
for _ in range(N):
trie.insert(In())
ans = 0
for _ in range(M):
if trie.search(In()):
ans += 1
print(ans)
Reference
この問題について(トリプル(Trie)), 我々は、より多くの情報をここで見つけました https://velog.io/@seilk/트라이Trieテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol