์ง๋๋ฒ์ ํธ๋ผ์ด๋ฅผ ๊ณต๋ถํ๊ณ ํฌ์คํ ์ผ๋ก ์ ๋ฆฌํ๋๋ฐ, ์๋ ํฌ์คํ ์์๋ Map Interface๋ก ๊ตฌํ์ ํ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ๋ฐฑ์ค - ์ ์ค(19585)์ ํธ๋ผ์ด ์๋ฃ๊ตฌ์กฐ๋ก ํ์ด๋ ์๊ฐ ์ด๊ณผ๊ฐ ๋๊ธธ๋ ๋ ์ฐพ์๋ณด๋ Array๋ก ๊ตฌํํ๋ ๋ฐฉ์๋ ์์ด์ ์ด๋ฒ์๋ Array ๋ฐฉ์์ผ๋ก ๊ตฌํํ ํธ๋ผ์ด๋ ์ถ๊ฐํ์ต๋๋ค.
ํธ๋ผ์ด(Trie)๋?
ํธ๋ผ์ด(Trie)๋ ๋ฌธ์์ด์ ์ ์ฅํ๊ณ ํจ์จ์ ์ผ๋ก ํ์ํ๊ธฐ ์ํ ํธ๋ฆฌ ํํ์ ์๋ฃ๊ตฌ์กฐ๋ก, ์์ธํ๊ฑด ์ง๋๋ฒ ํฌ์คํ ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
[์๋ฃ๊ตฌ์กฐ] ํธ๋ผ์ด(Trie)
1. ํธ๋ผ์ด(Trie)๋?์ํ๋ ์์๋ฅผ ์ฐพ๊ธฐ์ํด ์์ฃผ ์ฌ์ฉ๋๋ ์ด์ง ๊ฒ์ ํธ๋ฆฌ ๋ฑ์์๋ ํ๊ฒ ์์๋ฅผ ์ฐพ๋๋ฐ์ O(logN)์ ์๊ฐ์ด ๊ฑธ๋ฆฝ๋๋ค.ํ์ง๋ง ๋ฌธ์์ด์ ๊ฒฝ์ฐ ๋ ๋ฌธ์์ด์ ๋น๊ตํ๊ธฐ ์ํด์๋ ๋ฌธ์์ด
coding-vvon.tistory.com
ํธ๋ผ์ด(Trie) ๊ตฌํ ๋ฐฉ์
ํธ๋ผ์ด(Trie)๋ ๋ ๊ฐ์ง ๋ฐฉ์์ผ๋ก ๊ตฌํํ ์ ์์ต๋๋ค.
- Array๋ฅผ ์ด์ฉํ์ฌ ๊ตฌํ
- Map Interface๋ฅผ ์ด์ฉํ์ฌ ๊ตฌํ
Array๋ก ๊ตฌํํ ๊ฒฝ์ฐ, ๋น ๋ฅธ ์ ์ฅ๊ณผ ํ์์ ํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ง๋ง ํ์ํ ๋ฉ๋ชจ๋ฆฌ์ ํฌ๊ธฐ๊ฐ ๋๋ฌด ํฌ๋ค๋ ๊ฒ์ด ๋จ์ ์ ๋๋ค.
Map Interface๋ก ๊ตฌํํ ๊ฒฝ์ฐ, ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋์ ์ผ๋ก ํ ๋นํ์ฌ ํ์ ๋ ธ๋๋ง ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ ์ ์๋ค๋ ์ฅ์ ์ด ์์ง๋ง ๋ฉ๋ชจ๋ฆฌ ์ ํ์ด ์๋ ๊ฒฝ์ฐ ์ต์ ํ ์์ ์ด ๊ฝค ๊น๋ค๋กญ๋ค๋ ๋จ์ ์ด ์์ต๋๋ค.
1. Array๋ก ๊ตฌํ
Array๋ก ๊ตฌํํ ๊ฒฝ์ฐ, Trie์ Node๋ณ ์์ ๋ ธ๋๋ฅผ Nodeํ ๋ฐฐ์ด๋ก ๊ตฌํํฉ๋๋ค.
์ด๋, Trie Node์ ๋ค์ด๊ฐ๋ ๋จ์ด๋ ์์ด ์๋ฌธ์๋ง ์๋ค๊ณ ๊ฐ์ ํ๋ฉฐ, ๊ฐ ๋ ธ๋๋ ์์ด ์๋ฌธ์๋ฅผ ์ ์ํ(int)์ผ๋ก ๋ณํํ์ฌ ์ธ๋ฑ์ค๋ก ์ฌ์ฉํฉ๋๋ค.
* ์์ธํ ์ค๋ช ์ ์ด์ ํฌ์คํ ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
[์๋ฃ๊ตฌ์กฐ] ํธ๋ผ์ด(Trie)
1. ํธ๋ผ์ด(Trie)๋?์ํ๋ ์์๋ฅผ ์ฐพ๊ธฐ์ํด ์์ฃผ ์ฌ์ฉ๋๋ ์ด์ง ๊ฒ์ ํธ๋ฆฌ ๋ฑ์์๋ ํ๊ฒ ์์๋ฅผ ์ฐพ๋๋ฐ์ O(logN)์ ์๊ฐ์ด ๊ฑธ๋ฆฝ๋๋ค.ํ์ง๋ง ๋ฌธ์์ด์ ๊ฒฝ์ฐ ๋ ๋ฌธ์์ด์ ๋น๊ตํ๊ธฐ ์ํด์๋ ๋ฌธ์์ด
coding-vvon.tistory.com
Node ํด๋์ค ์์ฑ
Map์ผ๋ก ๊ตฌํํ Trie ์ Node์ ๋ค๋ฅด๊ฒ ์์ ๋ ธ๋๋ฅผ Node[] ๋ก ์ด๊ธฐํํฉ๋๋ค.
childNode์ ์ธ๋ฑ์ค์ ์์ด ์๋ฌธ์๋ฅผ ์ ์ํ(int)๋ก ๋ณํํ ๊ฐ์ด ๋ค์ด๊ฐ๊ฒ ๋ฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ์์ ๋ ธ๋์ ์(childCnt)์ ํด๋น ๋ ธ๋์ ๋ฌธ์(val)๋ ์ ์ฅํด์ค๋๋ค.
static final int SIZE = 26; // ์์ด ์๋ฌธ์๋ 26์
private class Node {
Node[] childNode = new Node[SIZE]; // ์์ ๋
ธ๋: ์์ด ์๋ฌธ์๋ฅผ ์ธ๋ฑ์คํ ํ์ฌ ์ ์ฅ
boolean endOfWord; // ๋จ์ด์ ๋์ธ์ง์ ๋ํ ํ๋๊ทธ
int childCnt = 0; // ์์ ๋
ธ๋ ์
char val; // ๋
ธ๋์ ๋ฌธ์
}
ํธ๋ผ์ด(Trie) ์๋ฃ๊ตฌ์กฐ ํด๋์ค ์์ฑ
public class TrieArray {
private Node rootNode;
public TrieArray() {
rootNode = new Node();
}
}
๊ธฐ๋ณธ ๋ฉ์๋
1) ๋ ธ๋ ์ถ๊ฐ(insert)
๋ฌธ์์ด์ ๋ฌธ์๋ฅผ ์ํํ๋ฉด์ ํด๋น ๋ฌธ์๊ฐ ์์๋ ธ๋๋ก ์๋์ง ํ์ธํ์ฌ ๋ ธ๋๋ฅผ ์ถ๊ฐํ๋ ๋ฉ์๋์ ๋๋ค.
Map์ผ๋ก ๊ตฌํํ์๋์๋ ๋ค๋ฅด๊ฒ ํ ๋ ธ๋์ ์์ ๋ ธ๋๊ฐ null ์ด ์๋์ง, ์ฆ, ์์ฑ๋์ด์๋์ง๋ฅผ ํ์ธํ์ฌ, ์๋ค๋ฉด ์์ฑํฉ๋๋ค.
์์ฑ์์๋ ์์ ๋ ธ๋๋ฅผ ์ถ๊ฐํ๊ณ , ์์ ๋ ธ๋์ ๋ฌธ์๋ฅผ ํ ๋นํด์ฃผ๊ณ , ํ ๋ ธ๋์ ์์ ๋ ธ๋ ์๋ฅผ ์ฆ๊ฐ์ํต๋๋ค.
public void insert(String word) {
Node node = this.rootNode;
// ๋จ์ด์ ๋ฌธ์๋ฅผ ์ํํ๋ฉด์ ์์ ๋
ธ๋ ํ์ธ
for (int i=0; i < word.length(); i++) {
char c = word.charAt(i);
// ๋จ์ด์ ํน์ ๋ฌธ์๋ฅผ ์ธ๋ฑ์ค(int)๋ก ๋ณํ
int intVal = charToInt(c);
// ํ ๋
ธ๋์ ์ธ๋ฑ์ค๋ก ๋ณํํ ๋ฌธ์๊ฐ ์์๋
ธ๋๋ก ์๋์ง ํ์ธ
if (node.childNode[intVal] == null) {
// ์์ ๋
ธ๋์ ์๋ ๋ฌธ์๋ผ๋ฉด ์๋ก ์์ฑ
node.childNode[intVal] = new Node();
node.childNode[intVal].val = c;
node.childCnt++;
}
// ๋ค์ ํ์ ๋
ธ๋๋ฅผ ์์๋
ธ๋๋ก ๋ณ๊ฒฝ
node = node.childNode[intVal];
}
node.endOfWord = true; // ๋จ์ด(word)์ ๋ฌธ์๋ฅผ ๋ชจ๋ ์ํํ๋ฉด ๋ง์ง๋ง ๋
ธ๋๋ ๋ฆฌํ ๋
ธ๋(=๋ง์ง๋ง ๋ฌธ์)์ด๊ธฐ๋๋ฌธ์ endOfWord๋ฅผ true๋ก ์ค์
}
2) ํฌํจ ์ฌ๋ถ ํ์ธ(contains)
๋ฌธ์์ด์ด ํธ๋ผ์ด์ ์๋์ง ํ์ธํ๋ ๋ฉ์๋๋ก, ๋ฐฐ์ด ๋ฐฉ์์ ๋ง๊ฒ ๊ตฌํํด์ฃผ๋ฉด ๋ฉ๋๋ค.
public boolean contains(String word) {
Node node = this.rootNode;
char c;
for (int i=0; i<word.length(); i++) {
c = word.charAt(i);
int intVal = charToInt(c); // ๋ฌธ์๋ฅผ ์ธ๋ฑ์ค๋ก ๋ณํ
if (node.childNode[intVal] == null) return false; // ํ์ฌ ํ์ํ๋ ๋ฌธ์๊ฐ ์์ ๋
ธ๋์ ์๋ค๋ฉด ์กด์ฌํ์ง ์๋ ๋จ์ด
node = node.childNode[intVal];
}
return node != null && node.endOfWord; // ๋ง์ง๋ง ๋ฌธ์ ์ฌ๋ถ๋ฅผ ๋ฐํ
}
3) ๋ ธ๋ ์ญ์ (delete)
ํธ๋ผ์ด์ ์กด์ฌํ๋ ๋ฌธ์์ด์ ์ญ์ ํ๋ ๋ฉ์๋๋ก, ์ญ์ ์กฐ๊ฑด์ ๋ง์ถฐ ๋ฐฐ์ด ๋ฐฉ์์ ๋ง๊ฒ ๊ตฌํํด์ฃผ๋ฉด ๋ฉ๋๋ค.
public void delete(String word) {
delete(this.rootNode, word, 0);
}
// ์ฌ๊ท ํธ์ถ์ ์ํ ํจ์ ์ค๋ฒ๋ก๋ฉ
public void delete(Node node, String word, int idx) {
// ๋จ์ด์ ๋ง์ง๋ง์ธ ๊ฒฝ์ฐ
if (idx == word.length()) {
if (!node.endOfWord) throw new Error(word + " not exist"); // ๋จ์ด๊ฐ ์กด์ฌํ์ง ์์
node.endOfWord = false; // ๋จ์ด์ ๋ ๋ฌธ์ ํ์๋ฅผ false๋ก ๋ณ๊ฒฝ: ํด๋น ๋ฌธ์ ๋
ธ๋๋ฅผ ์ญ์ ํ๊ธฐ ์ํจ
return; // ๋ฆฌํ ๋
ธ๋์ ๋ถ๋ชจ ๋
ธ๋๋ก return
} else {
if (node.childCnt == 0) throw new Error(word + " not exist"); // ์์ ๋
ธ๋๊ฐ ์๋ ๊ฒฝ์ฐ(=๋จ์ด๊ฐ ์กด์ฌํ์ง ์๋ ๊ฒฝ์ฐ)
}
char c = word.charAt(idx); // ํ์ฌ ํ์ธํด์ผํ๋ ๋ฌธ์
int intVal = charToInt(c); // ๋ฌธ์๋ฅผ ์ธ๋ฑ์ค๋ก ๋ณํ
Node child = node.childNode[intVal]; // ์์ ๋
ธ๋ ๊ฐ์ ธ์ค๊ธฐ
// ์์ ๋
ธ๋๊ฐ ์๋ค๋ฉด ๋ฆฌํ ๋
ธ๋๊น์ง ๋ด๋ ค๊ฐ์ผ ํ๋ฏ๋ก ์ฌ๊ท ํธ์ถ
delete(child, word, idx+1);
// ํ ๋
ธ๋์ ์์ ๋
ธ๋๊ฐ ์ญ์ ๋์๋ค๋ฉด, ํ ๋
ธ๋์ ์์ ๋
ธ๋ ์ 1 ์ฐจ๊ฐ
if (node.childNode[intVal] == null) node.childCnt--;
// ํ ๋
ธ๋์ ์์ ๋
ธ๋๊ฐ ๋ฆฌํ ๋
ธ๋์ด๊ณ (=์์ ๋
ธ๋๊ฐ ์์), ๋จ์ด์ ๋์ธ ๋ฌธ์๊ฐ ์๋๋ผ๋ฉด ์ญ์
if (child.childCnt == 0 && !node.endOfWord) node = null;
}
๐งช ๊ตฌํ ํ ์คํธ
๊ตฌํ ํ ์คํธ๋ Map ๋ฐฉ์๊ณผ ๋์ผํ๋, ํด๋น ํฌ์คํ ์ ์ฐธ๊ณ ํด์ฃผ์ธ์ :)
๐ก ์ ์ฒด ์ฝ๋(Array๋ก ๊ตฌํ)๋ ์๋ ๋งํฌ์์ ํ์ธํด์ฃผ์ธ์.
Algorithm/src/Trie/TrieArray.java at main · hywnj/Algorithm
Contribute to hywnj/Algorithm development by creating an account on GitHub.
github.com
2. Map Interface๋ก ๊ตฌํ
์๋ ์ฝ๋๋ Map Interface๋ก ๊ตฌํํ ์ฝ๋์ด๋ฉฐ, ์์ธํ ์ค๋ช ์ ์ด์ ํฌ์คํ ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
[์๋ฃ๊ตฌ์กฐ] ํธ๋ผ์ด(Trie)
1. ํธ๋ผ์ด(Trie)๋?์ํ๋ ์์๋ฅผ ์ฐพ๊ธฐ์ํด ์์ฃผ ์ฌ์ฉ๋๋ ์ด์ง ๊ฒ์ ํธ๋ฆฌ ๋ฑ์์๋ ํ๊ฒ ์์๋ฅผ ์ฐพ๋๋ฐ์ O(logN)์ ์๊ฐ์ด ๊ฑธ๋ฆฝ๋๋ค.ํ์ง๋ง ๋ฌธ์์ด์ ๊ฒฝ์ฐ ๋ ๋ฌธ์์ด์ ๋น๊ตํ๊ธฐ ์ํด์๋ ๋ฌธ์์ด
coding-vvon.tistory.com
๐ก Trie๋ฅผ Map, Array๋ก ๊ตฌํํ ์ฝ๋๋ ์๋ ๋งํฌ์์ ํ์ธํด์ฃผ์ธ์.
Algorithm/src/Trie at main · hywnj/Algorithm
Contribute to hywnj/Algorithm development by creating an account on GitHub.
github.com
Reference
[์๋ฃ๊ตฌ์กฐ | Java] Trie(ํธ๋ผ์ด)
์ด๋ฒ ์๊ฐ์๋ ์๋ฃ๊ตฌ์กฐ ํธ๋ผ์ด์ ๋ํด ์์๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค. 1. ํธ๋ผ์ด(Trie)๋? ํจ์จ์ ์ธ ๋ฌธ์์ด ์ ์ฅ ๋ฐ ํ์์ด ๊ฐ๋ฅํ๋๋ก ๋ง๋ ์๋ฃ๊ตฌ์กฐ ํํ ์ค ํ๋์ ๋๋ค. ์ฝ๋ฉ์ ํ๋ค ๋ณด๋ฉด ์๋ง์ ๋ฌธ
cdragon.tistory.com
'๐ฌ Computer Science > Algorithm' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[์๋ฃ๊ตฌ์กฐ] ๋ชจ๋ ธํค ์คํ(Monotone stack) (0) | 2024.07.17 |
---|---|
[์๋ฃ๊ตฌ์กฐ] ํธ๋ผ์ด(Trie) (0) | 2024.05.08 |