๊ฐ์
ํธ๋ผ์ด
๋ฌธ์์ด์ ์ ์ฅํ๊ณ ํจ์จ์ ์ผ๋ก ํ์ํ๊ธฐ ์ํย
ํธ๋ฆฌย ํํ
- ์ฅ๋จ์
- ์๊ฐ๋ณต์ก๋๋ O(L: ํ์ ๋ฌธ์์ด ๊ธธ์ด) ๋ก, ๋ฌธ์ ํ๋ํ๋ ๋น๊ตํ๋ ๊ฒ์ ๋นํด ํจ์จ์ ์ด๋ค.
- ๊ฐ ๋
ธ๋๋ง๋ค ์์์ ํฌ์ธํฐ๋ฅผ ๋ชจ๋ ์ ์ฅํ๊ณ ์์ด, ๋ฉ๋ชจ๋ฆฌ ์๋น๊ฐ ํฌ๋ค.

์๋ฆฌ
ํธ๋ผ์ด์ ๊ตฌ์กฐ
- ๋ฃจํธ๋ ์๋ฌด๋ฐ ๊ฐ์ด ์๋ค.
- ์ฝ์ ํ ๋ฌธ์์ด์ ๋ฌธ์๋ฅผ ๊ฐ๊ฐ ๋ ธ๋๋ก ๋ง๋ค์ด, ๋ถ๋ชจ-์์์ผ๋ก ์ฐ๊ฒฐ์ง๋๋ค.
- ๋ฌธ์์ด์ ๋ง์ง๋ง ๋ฌธ์๋ ํด๋น ๋ฌธ์์ด์ ์ข
๋ฃ ์ง์ ์ ๋ํ๋ด๋ ํ๋๊ทธ๋ฅผ
True๋ก ์ค์ ํ๋ค. ์์ ๊ทธ๋ฆผ์์ ๋ ธ๋์ ๋ ธ๋๋ค์ ๋จ์ด์ ๋ง์ง๋ง ๋ฌธ์์ฌ์ Flag๊ฐ True์ด๋ค.
๊ตฌํ
ํธ๋ผ์ด์ ๋ ธ๋
๋ ธ๋์ ๊ตฌ์ฑ์์
3๊ฐ์ง์ ํ์ ์ ๋ณด๊ฐ ํ์ํ๋ค.
- ๋ฌธ์ ๊ฐ
- ์์ ๋ ธ๋ ํฌ์ธํฐ๋ฅผ ์ ์ฅํ ์๋ฃ๊ตฌ์กฐ(์ฃผ๋ก ๋์ ๋๋ฆฌ)
- ํด๋น ๋ ธ๋๊ฐ ๋จ์ด์ ๋ง์ง๋ง์ธ์ง ๋ํ๋ด๋ Flag
class TrieNode:
def __init__(self, character=None):
self.c = character
self.children = {} # key: ์์ ๋
ธ๋์ ๋ฌธ์, value: ์์ ๋
ธ๋
self.is_end = False # ํด๋น ๋ฌธ์๋ฅผ ๋ง์ง๋ง์ผ๋ก ํ๋ ๋ฌธ์์ด ์กด์ฌ ์ ๋ฌด
def append(self, child_char, child_node):
self.children[child_char] = child_node
def pop(self, child_char):
if child_char in self.children:
del self.children[child_char]ํธ๋ผ์ด ๋ณธ์ฒด
์ด๊ธฐํ
class Trie:
def __init__(self):
self.head = TrieNode()์กฐํ
# ์ ํํ ๋ฌธ์ ํ์
def search(self, string):
current = self.head
for c in string:
# ๋ค์ ๋ฌธ์๊ฐ ์กด์ฌํ๋์ง ํ์ธ
if c not in current.children:
return False
current = current.children[c]
# Flag ํ์ธ
return current.is_end์ฝ์
def add(self, string):
if len(string) == 0:
return
current = self.head
for c in string:
# ํด๋น ๋ฌธ์์ ์์ ๋
ธ๋๊ฐ ์์ผ๋ฉด ์ถ๊ฐ
if c not in current.children:
current.children[c] = TrieNode(c)
current = current.children[c]
# Flag ์ค์
current.is_end = True์ญ์
์ญ์ ๊ธฐ๋ฅ์ด ์กฐ๊ธ ๋ณต์กํ๋ค.
์๋ฆฌ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- ๋ง์ง๋ง ๋ฌธ์๊น์ง ์ํํ๋ฉด์ (๋ถ๋ชจ ๋
ธ๋, ํ์ฌ ๋ฌธ์) ์คํ์ ๋ง๋ ๋ค.
- ๋ ธ๋๋ฅผ ์ญ์์ผ๋ก ์ง์ฐ๊ธฐ ์ํจ
- ์ญ์์ผ๋ก ์์๋
ธ๋์ Flag์
children์ ํ์ธํ๋ฉฐ ์ญ์ ์ฒ๋ฆฌํ๋ค.- Flag๊ฐ
false์ด๊ณ ,children์ด ์๋ ๊ฒฝ์ฐ์๋ง ๋ ธ๋๋ฅผ ์ญ์
- Flag๊ฐ
- ๋ฐ๋ณต์ ์ผ๋ก ๋ถ๋ชจ๋ ธ๋์ ๋ํด 2๋ฒ์ ๋ฐ๋ณตํ๋ค.
def delete(self, string):
# (๋ถ๋ชจ ๋
ธ๋, ๋ฌธ์) ์คํ
stack = []
current = self.head
# ์คํ ์ด๊ธฐํ
for c in string:
# ์กด์ฌํ๋ ๋ฌธ์์ธ์ง ํ์ธ
if c not in current.children:
return False
stack.append((current, c))
current = current.children[c]
# ์กด์ฌํ๋ ๋ฌธ์์ด์ธ์ง ํ์ธ
if not current.is_end:
return False
# Flag ์ค์
current.is_end = False
# ๋ง์ง๋ง ๋ฌธ์์ ์์ ๋
ธ๋๊ฐ ์์ผ๋ฉด ์ข
๋ฃ
if current.children:
return True
# ๋ถ๋ชจ๋
ธ๋๋ก ์ฌ๊ท ์งํ: ์์ ๋
ธ๋๊ฐ ์๊ณ Flag๊ฐ False์ฌ์ผ ํ๋ค.
for parent, char in reversed(stack):
del parent.children[char]
if parent.is_end or parent.children:
break
return True์ ์ฒด ์ฝ๋
class TrieNode:
def __init__(self, character=None):
self.c = character
self.children = {}
self.is_end = False
def append(self, child_char, child_node):
self.children[child_char] = child_node
def pop(self, child_char):
if child_char in self.children:
del self.children[child_char]
class Trie:
def __init__(self):
self.head = TrieNode()
def add(self, string):
if len(string) == 0:
return
current = self.head
for c in string:
if c not in current.children:
current.children[c] = TrieNode(c)
current = current.children[c]
current.is_end = True
def delete(self, string):
# (๋ถ๋ชจ ๋
ธ๋, ๋ฌธ์) ์คํ
stack = []
current = self.head
# ์คํ ์ด๊ธฐํ
for c in string:
# ์กด์ฌํ๋ ๋ฌธ์์ธ์ง ํ์ธ
if c not in current.children:
return False
stack.append((current, c))
current = current.children[c]
# ์กด์ฌํ๋ ๋ฌธ์์ด์ธ์ง ํ์ธ
if not current.is_end:
return False
# Flag ์ค์
current.is_end = False
# ๋ง์ง๋ง ๋ฌธ์์ ์์ ๋
ธ๋๊ฐ ์์ผ๋ฉด ์ข
๋ฃ
if current.children:
return True
# ๋ถ๋ชจ๋
ธ๋๋ก ์ฌ๊ท ์งํ: ์์ ๋
ธ๋๊ฐ ์๊ณ Flag๊ฐ False์ฌ์ผ ํ๋ค.
for parent, char in reversed(stack):
del parent.children[char]
if parent.is_end or parent.children:
break
return True
# ์ ํํ ๋ฌธ์ ํ์
def search(self, string):
current = self.head
for c in string:
if c not in current.children:
return False
current = current.children[c]
return current.is_end