Trie(ํธ๋ผ์ด) ์๊ณ ๋ฆฌ์ฆ
๋ฌธ์์ด ์ ์ฅ Trie(ํธ๋ผ์ด) ์๊ณ ๋ฆฌ์ฆ C++
Trie ์๊ณ ๋ฆฌ์ฆ
์ ๋ฌธ์์ด์ ์ ์ฅํ๊ณ , ํด๋น ๋ฌธ์์ด์ ์ ์ฅ ์ ๋ฌด๋ฅผ ํ์ธํ ๋ ์ฐ๋ ์๊ณ ๋ฆฌ์ฆ์
๋๋ค.
์์
"vivid"
๋ผ๋ ๋ฌธ์์ด์ ์ ์ฅํ๋ค๊ณ ๊ฐ์ ํฉ์๋ค.
๊ฐ์ฅ ๋งจ ์์ ์๋ฃ๋ฅผ ์ ์ฅํ ๋ฃจํธ ๋
ธ๋๊ฐ ์์ ๊ฒ์ด๊ณ , ๊ทธ ๋ฃจํธ ๋
ธ๋ ์๋ v๋ฅผ ์ ์ฅ,
v๊ฐ ์ ์ฅ๋์ด ์๋ ๋
ธ๋ ์๋ i๊ฐ ์ ์ฅ
i๊ฐ ์ ์ฅ๋์ด ์๋ ๋
ธ๋ ์๋ v๋ฅผ ์ ์ฅ.. ์ด๋ฐ ์์ผ๋ก ๋ง์ง๋ง d๊น์ง ์ ์ฅํฉ๋๋ค.
์ฌ๊ธฐ์ ๊ฐ์ฅ ๋ง์ง๋ง ๋ฌธ์์ด์ธ vivid์ d ๋ค์ ๋ฌธ์์ด์ ๋์ ์๋ฆฌ๋ '\0'์ด ๋ถ์ด์์ ๊ฒ์ด๋ฏ๋ก, ์ด๋ฅผ d ๋
ธ๋์ ํ์
(๋
ธ๋์ ๋
ธ๋)๋ฅผ ํด์ค์๋ค.
์ด๋ฐ ์์ผ๋ก ๋ฃจํธ ๋
ธ๋ ์๋ ์ ์ฅํ ๋จ์ด๋ค์ ๋
ธ๋๋ฅผ ํ์ฅ ์ํต๋๋ค."vivid"
์ธ์ "sw"
, "swan"
, "sweet"
๋ฅผ ์ถ๊ฐํด๋ณด๋ฉด ์๋์ ๊ฐ์ต๋๋ค.
์๊ฐ, ๊ณต๊ฐ ๋ณต์ก๋
ํธ๋ผ์ด๋ ๊ฐ ๋ฌธ์๋ง๋ค ์ธ๋ฑ์ฑ์ ํด์ ์๋ฃ๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ํ์ํ๊ธฐ ๋๋ฌธ์, ์ฐพ๋ ๋ฌธ์์ด์ ๋ฌธ์ ์๊ฐ N ๊ฐ๋ผ๋ฉด N ๋ฒ๋ง์ ํน์ ๋ฌธ์์ด์ ์ ๋ฌด๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
ํ์ง๋ง, ์ธ๋ฑ์ฑ์ ํ๋ฉด์ ๋ฌธ์๋ฅผ ์ฝ์ ํ๊ธฐ ๋๋ฌธ์, ์ต์ ์ ๊ฒฝ์ฐ์ ๊ฐ๋ฅํ ๋ฌธ์ ์๊ฐ M ๊ฐ๋ผ๊ณ ํ๋ค๋ฉด N ๊ฐ๊น์ง์ ์ ํ์ด ์๋ ๋ฌธ์์ด์์ ์ต์ ์ ๊ฒฝ์ฐ M^N์ ๊ณต๊ฐ ๋ณต์ก๋๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์, ๋ค๋ฅธ ์๊ณ ๋ฆฌ์ฆ๋ค ๋ณด๋ค ๋ง์ ๊ณต๊ฐ ๋ณต์ก๋๋ฅผ ์๊ตฌํฉ๋๋ค.
๊ตฌํ
CPP์์ Trie๋ฅผ ๋ณดํต ๊ตฌ์กฐ์ฒด์ ํฌ์ธํฐ ๋ฐฐ์ด๋ก ๊ตฌํํฉ๋๋ค.
๊ตฌ์กฐ์ฒด์ ๋ค์ ์ธ๋ฑ์ฑ ๋
ธ๋์ ํฌ์ธํฐ ๋ฐฐ์ด๋ค์ ๋ชจ๋ nullptr
๋ก ์ ์ธํ ๋ค, ํด๋น ๊ณต๊ฐ์ด ํ์ํ ๋ ์๋ก์ด ๊ตฌ์กฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ค๋๋ค.
๊ฐ ๋
ธ๋์๋ ํ์ํ ๊ฐ๋ค์ ์ ์ฅํด ์ค๋ค. ์๋ฅผ ๋ค์ด, ์ ๊ทธ๋ฆผ์ ๋ค์ ๋ฌธ์๊ฐ '\0'์ธ ๊ฒฝ์ฐ๋ boolํ์ผ๋ก ์ฒดํฌํด ์ฃผ๊ณ ์ด์ฉํฉ๋๋ค.
๋ค ์ด Trie๋ ๋์ ํ ๋น ํด์ ๋ฅผ ํด์ฃผ์ด์ผ ํฉ๋๋ค.
Trie์ ๋ํ ๋ฌธ์ ๋ฅผ ์ดํด๋ด
์๋ค.
๋ฌธ์ : BOJ_5052๋ฒ ์ ํ๋ฒํธ ๋ชฉ๋ก
๋ฌธ์ ๋ฅผ ์ฐจ๊ทผ์ฐจ๊ทผ ์ฝ์ด๋ณด๋ฉด, ์ผ๊ด์ฑ์ ํ๋ณํ๊ธฐ ์ํด์ ๊ฒฐ๊ตญ ๋ค์ ๋ฌธ์๊ฐ '\0' ์ธ ๊ฒฝ์ฐ๋ก ์ฒดํฌ๋์๋๋ฐ, ๋ค๋ฅธ ๋ฌธ์๋ ์์ ๋
ธ๋๋ก ๊ฐ๊ณ ์์ผ๋ฉด ์ผ๊ด์ฑ์ ์ด๊ธ๋๊ฒ ๋ฉ๋๋ค.
์ ์ฒด ์์ค์ ๋๋ค.
#include <iostream>
#include <cstring>
using namespace std;
bool isConsistent = true;
struct Trie {
bool isWord;
bool existChild;
Trie* childTrie[10];
Trie() {
isWord = false;
existChild = false;
for (int i = 0; i < 10; i++) childTrie[i] = nullptr;
}
~Trie() {
for (int i = 0; i < 10; i++) {
if (childTrie[i]) delete childTrie[i];
}
}
void insert(char* word) {
if (*word == '\0') isWord = true;
else {
int next = *word - '0';
if (!childTrie[next]) childTrie[next] = new Trie;
existChild = true;
childTrie[next]->insert(word + 1);
}
if (isWord && existChild) isConsistent = false;
}
};
int main(void) {
int T;
cin >> T;
for (int i = 0; i < T; i++) {
isConsistent = true;
Trie* trie = new Trie;
int N;
cin >> N;
for (int j = 0; j < N; j++) {
char word[11];
cin >> word;
trie->insert(word);
}
if (isConsistent) cout << "YES\n";
else cout << "NO\n";
delete trie;
}
}
์ฐจ๊ทผ์ฐจ๊ทผ ์์ค๋ฅผ ํ์ธํด๋ณด๋ฉด,
struct Trie {
bool isWord;
bool existChild;
Trie* childTrie[10];
Trie() {
isWord = false;
existChild = false;
for (int i = 0; i < 10; i++) childTrie[i] = nullptr;
}
~Trie() {
for (int i = 0; i < 10; i++) {
if (childTrie[i]) delete childTrie[i];
}
}
}
๋๋๋ ๋ฌธ์์ด์ธ๊ฐ์ ์ ๋ฌด์ธ isWord, ์์ ๋
ธ๋๋ฅผ ์ ์ฅํ๋์ง ์ ๋ฌด์ธ existChild, ์์ ๋
ธ๋์ ํฌ์ธํฐ ๋ฐฐ์ด์ ๊ฐ๊ณ ์์ต๋๋ค.
์์ฑํ ๋ for (int i = 0; i < 10; i++) childTrie[i] = nullptr;
๋ก ํฌ์ธํฐ ๋ฐฐ์ด์ ๋ชจ๋ null๋ก ์ธํ
ํฉ๋๋ค.
void insert(char* word) {
if (*word == '\0') isWord = true;
else {
int next = *word - '0';
if (!childTrie[next]) childTrie[next] = new Trie;
existChild = true;
childTrie[next]->insert(word + 1);
}
if (isWord && existChild) isConsistent = false;
}
์ฝ์
ํ๋ ๊ณผ์ ์
๋๋ค. ์ฝ์
ํด์ผ ํ๋ ๋ฌธ์์ด์ด '\0'์ด๋ผ๋ฉด, isWord๋ฅผ true๋ก ํด์ฃผ๊ณ ์ข
๋ฃ,
'\0'์ด ์๋๋ผ๋ฉด ์ธ๋ฑ์ฑ์ ๋ง๊ฒ ๋ค์ ๋ฌธ์๋ฅผ ์ฝ์
ํด ์ค๋๋ค.
์ด๋ ์ธ๋ฑ์ฑ์ ๋ง๋ ํฌ์ธํฐ ๋ฐฐ์ด์ด null์ด๋ผ๋ฉด Trie ๋
ธ๋๋ฅผ ์์ฑํด ์ฃผ๊ณ , ์์ ๋
ธ๋์ ์ ๋ฌด์ธ existChild
๋ true๋ก ์ฒดํฌํฉ๋๋ค.
๋ง์ง๋ง ์ค์ if (isWord && existChild) isConsistent = false;
๋ ์ผ๊ด์ฑ์ ํ๋จํ๋ ๋ถ๋ถ์
๋๋ค.
์๋ฐ๋ก๋ Trie๋ฅผ ์งค ์ ์์ต๋๋ค.
์๋ฐ๋ ํฌ์ธํฐ ๋ฐฐ์ด์ด ํ์ ์์ด new๋ก ํ ์์ญ์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค ์ ์๊ณ , ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ๋์ ํ ๋น ํด์ ๋ฅผ ํด์ค๋ค๋ ์ฅ์ ์ด ์์ต๋๋ค.
์๋๋ ๋๊ฐ์ ๋
ผ๋ฆฌ๋ก ์์ ๋ฌธ์ ๋ฅผ ์๋ฐ๋ก ํ์ดํ ๊ฒ์
๋๋ค.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Java_5052_์ ํ๋ฒํธ๋ชฉ๋ก {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int T = Integer.parseInt(br.readLine());
for(int i=0;i<T;i++) {
int n = Integer.parseInt(br.readLine());
Trie trie = new Trie();
for(int j=0;j<n;j++) {
String word = br.readLine();
trie.insert(word);
}
if(Trie.isConsistency) System.out.println("YES");
else System.out.println("NO");
Trie.isConsistency=true;
}
}
}
class Trie {
static boolean isConsistency=true;
// ์ ์ ๋ณ์
boolean isWord = false;
boolean existChild = false;
// ๋ํดํธ ์์ฑ
Trie[] childTrie = new Trie[10];
void insert(String word) {
int len = word.length();
Trie nowTrie = this;
for(int i=0;i<len;i++) {
int nextNum = word.charAt(i)-'0';
if(nowTrie.childTrie[nextNum]==null) nowTrie.childTrie[nextNum] = new Trie();
nowTrie = nowTrie.childTrie[nextNum];
// ์์ ๊ทธ๋ํ๋ก ์ด๋
if(i==len-1) nowTrie.isWord=true;
else nowTrie.existChild=true;
if(nowTrie.isWord && nowTrie.existChild) isConsistency = false;
}
}
}