trie - changicho/algorithm-training GitHub Wiki
ํธ๋ผ์ด
๋ฌธ์
์ค๋ช
ํธ๋ผ์ด๋ ๋ฌธ์์ด์ ํจ์จ์ ์ผ๋ก ์ ์ฅํ๊ณ ํ์ํ ์ ์๋ K์ง ํธ๋ฆฌ์ ์๋ฃ๊ตฌ์กฐ์ด๋ค.
์ํ๋ ๋ฌธ์์ด์ ์ฐพ๋ ๋ฐ ๋ค์ด๊ฐ๋ ์๊ฐ ๋ณต์ก๋๋ O(N)์ด๋ค.
๊ฐ ๋จ๊ณ๋ง๋ค ๋ฌธ์์ด๋ค์ key๋ก ์ค์ ํ๊ณ ์ดํ ํ์์ ์งํํ๋ ๋ฐฉ์์ผ๋ก ํ์์ ์ต์ ํํ๋ค.
์ด๋ ์ค๋ณต๋ ๋จ๊ณ์์ ๋ฌธ์์ด์ด ์ด๋จ๋๋ ๋ง์ง๋ง ๋ฌธ์์ด์ผ์๋, ์๋์๋ ์๊ธฐ ๋๋ฌธ์ boolean์ผ๋ก ์ด ๋จ๊ณ๊ฐ ๋์ธ์ง ์ฌ๋ถ๋ํ ์ ์ฅํ๋ค.
๋ฃจํธ ๋ ธ๋์ ๊ฒฝ์ฐ key๊ฐ์ด ์์์ ์ ์ํ๋ค.
๊ตฌํ
TrieNode์ ๊ตฌํ์ ๋ค์๊ณผ ๊ฐ๋ค.
// use array
struct TrieNode {
// ๋ชจ๋ char์ ๋ํด ์ ์ธํ์ผ๋ฏ๋ก ๋ฌธ์ ์ ์ฃผ์ด์ง 26์์ ๋ํด์๋ง ์ต์ ํ๋ ๊ฐ๋ฅํ๋ค
struct TrieNode *children[256] = {
NULL,
};
bool isEnd = false;
};
// use hashmap
struct TrieNode {
unordered_map<char, TrieNode *> children;
bool isEnd;
TrieNode() { isEnd = false; }
};
์ด๋ฅผ ์ด์ฉํด ํธ๋ผ์ด๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ ์ ์๋ค.
class Trie {
private:
struct TrieNode {
unordered_map<char, TrieNode *> children;
bool isEnd;
TrieNode() { isEnd = false; }
};
TrieNode *root = new TrieNode;
public:
void insert(string word) {
TrieNode *node = root;
for (char c : word) {
if (!node->children[c]) {
node->children[c] = new TrieNode;
}
node = node->children[c];
}
node->isEnd = true;
}
bool search(string word) {
TrieNode *node = root;
for (char c : word) {
if (!node->children[c]) {
return false;
}
node = node->children[c];
}
return node && node->isEnd;
}
bool startsWith(string prefix) {
TrieNode *node = root;
for (char c : prefix) {
if (!node->children[c]) {
return false;
}
node = node->children[c];
}
return node;
}
};
์ญ์ ๊ฐ๋ฅํ ํธ๋ผ์ด
class Trie {
private:
struct TrieNode {
unordered_map<char, TrieNode *> children;
bool isEnd;
TrieNode() { isEnd = false; }
};
TrieNode *root = new TrieNode;
bool isEmpty(TrieNode *cur) {
if (cur->children.size() > 0) return false;
return true;
}
void erase(string &word, int index, TrieNode *cur) {
int length = word.length();
if (index == length) {
cur->isEnd = false;
return;
}
int key = word[index];
erase(word, index + 1, cur->children[key]);
if (isEmpty(cur->children[key])) {
cur->children[key] = NULL;
delete cur->children[key];
}
}
public:
void insert(string word) {
TrieNode *node = root;
for (char c : word) {
if (!node->children[c]) {
node->children[c] = new TrieNode;
}
node = node->children[c];
}
node->isEnd = true;
}
bool has(string word) {
TrieNode *node = root;
for (char c : word) {
if (!node->children[c]) {
return false;
}
node = node->children[c];
}
return node && node->isEnd;
}
bool startsWith(string prefix) {
TrieNode *node = root;
for (char c : prefix) {
if (!node->children[c]) {
return false;
}
node = node->children[c];
}
return node;
}
void erase(string word) { erase(word, 0, root); }
};