삼성 소프트웨어 (SW) 역량테스트 B형 준비! ② (Trie)
2019. 9. 17. 00:29ㆍ알고리즘/삼성SW역량테스트 B형 준비
문제
https://www.acmicpc.net/problem/5052
풀이
N = 10^5 이기 때문에, O(NlogN) 이하의 알고리즘이 필요합니다.
Trie 라는 자료구조는 문자열의 검색 및 업데이트에 최적화 되어있습니다.
Trie란? 문자열의 Search Tree 입니다. 위 그림처럼, 단어들의 첫 글자부터 하나씩 depth가 깊어지며 node를 만들기 시작합니다. Trie의 Update 및 Search 등은 Trie의 트리의 높이만큼의 시간뿐이 걸리지 않습니다. (매우빠름) |
위 문제에서는, 각 번호들로 Trie 를 만들면서 단어가 끝나는 지점에 표시를 해줍니다.
void Node::insert(char* word) {
if(word[0] == '\0') {
this->isLast = true;
return ;
}
char ch = word[0];
int ch_int = ch - '0';
if ( this->child[ch_int] != NULL ) {
this->child[ch_int]->insert(word + 1);
} else {
this->child[ch_int] = new Node();
this->child[ch_int]->value = ch;
this->child[ch_int]->insert(word + 1);
}
}
모든 번호들을 Insert 한 후에, 다시 각 단어별로 탐색을 시작합니다.
이 때 탐색하는 도중 번호의 끝이 아님에도 불구하고, 다른 단어의 끝나는 지점에 도착했다면 다른 번호가 탐색하는 번호의 접두어를 이루고 있다는 뜻이 됩니다.
bool Node::validate(char* word) {
if(word[0] == '\0') return true; // 탐색하는 단어의 끝인가?
if(this->isLast) return false; // 탐색하는 도중, isLast=true 인 node를 만났다. 즉 다른단어의 끝나는 지점을 만났다!
int ch_int = word[0] - '0';
return this->child[ch_int]->validate(word+1);
}
코드
/*
https://www.acmicpc.net/problem/5052
N = 10^5 이기 때문에,
O(NlogN) 이하의 알고리즘이 필요하다.
String의 접두어 관련 문제는 Trie 로 해결이 가능할 것으로 보인다.
*/
#include <iostream>
#include <fstream>
using namespace std;
ifstream fin;
ofstream fout;
class Node {
char value;
bool isLast = false;
Node *child[26];
public:
void insert(char* word);
bool validate(char* word);
};
void Node::insert(char* word) {
if(word[0] == '\0') {
this->isLast = true;
return ;
}
char ch = word[0];
int ch_int = ch - '0';
if ( this->child[ch_int] != NULL ) {
this->child[ch_int]->insert(word + 1);
} else {
this->child[ch_int] = new Node();
this->child[ch_int]->value = ch;
this->child[ch_int]->insert(word + 1);
}
}
bool Node::validate(char* word) {
if(word[0] == '\0') return true;
if(this->isLast) return false;
int ch_int = word[0] - '0';
return this->child[ch_int]->validate(word+1);
}
int main () {
// set fstream
fin.open("resource/input.txt");
fout.open("resource/output.txt");
int T;
cin >> T;
for ( int t = 0 ; t < T; t++ ) {
// input
int N;
int i;
cin >> N;
char a[N][11];
for ( i = 0; i < N; i++ ) {
cin >> a[i];
}
// make trie
Node* rootNode = new Node();
for ( i = 0; i < N; i++ ) {
rootNode->insert(a[i]);
}
for ( i = 0 ; i < N ; i++ ) {
if ( !rootNode->validate(a[i]) ) {
cout << "NO" << endl;
break;
}
}
if ( i == N ) cout << "YES" << endl;
}
return 0;
}
'알고리즘 > 삼성SW역량테스트 B형 준비' 카테고리의 다른 글
삼성 소프트웨어 (SW) 역량테스트 B형 준비! ① (BST) (0) | 2019.09.14 |
---|