반응형

Trie를 이전에는 재귀를 이용하여 만들었는데


이번에는 반복문을 통해 Trie를 구성하는 방법을 보고자 한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#include <iostream>
#include <cstdio>
#include <queue>
#include <string>
 
using namespace std;
 
const int MAX_NODE = 26;
struct Trie {
    Trie *next[MAX_NODE];
    bool isEnd;
    bool isVisited;
 
    Trie() {
        for (int i = 0; i < MAX_NODE; i++)
        {
            next[i] = nullptr;
            isEnd = isVisited = false;
        }
    }
    ~Trie() {
        for (int i = 0; i < MAX_NODE; i++)
            if (next[i])
                delete next[i];
    }
};
void search(Trie *root) {
    queue<pair<Trie*, string> > q;
    q.push({ root, "" });
 
    while (!q.empty())
    {
        Trie *cur = q.front().first;
        string str = q.front().second;
        q.pop();
 
        for (int i = 0; i < MAX_NODE; i++)
        {
            if (cur->isEnd && !cur->isVisited)
            {
                cout << "찾아낸 값 :: " << str << endl;
                cur->isVisited = true;
            }
            if (cur->next[i])
            {
                if (cur == root)
                {
                    cout << (char)(i + 'A'<< endl;
                    Trie *next = cur->next[i];
                    q.push({ next, str + (char)(i + 'A') });
                }
                else
                {
                    cout << str << " 다음 값 :: " << (char)(i + 'A'<< endl;
                    Trie *next = cur->next[i];
                    q.push({ next, str + (char)(i + 'A') });
                }
            }
        }
    }
}
 
int main()
{
    Trie *root = new Trie;
 
    for(int i = 0; i < 4; i++)
    {
        char tmp[10];
        scanf("%s", tmp);
 
        Trie *pos = root;
        for (int i = 0; tmp[i]; i++)
        {
            int nowCh = tmp[i] - 'a';
            if (pos->next[nowCh] == nullptr)
                pos->next[nowCh] = new Trie;
 
            pos = pos->next[nowCh];
        }
        pos->isEnd = true;
    }
 
    search(root);
    
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


우선 Trie 구조체를 위와 같이 형성한다.


이때 MAX_NODE는 트라이를 만들때 필요한 노드수만큼 만들어주면 된다.


그 후 생성자에는 포인터를 nullptr가 되도록, isEnd(단어의 끝인가?), isVisited(이전에 방문한 단어인가?)를 초기화 해둔다.


물론 위의 변수는 트라이를 만들 때 수정하면 된다.




이제 main문에서 *root = new Trie;를 통해 트라이를 생성해주고


문자열을 tmp에 입력받는다.


이제 마지막 for문이 Trie에 단어를 삽입하는 과정인데


pos는 root를 가르키게 하고, pos->next[nowCh] 즉, 현재 단어를 nowCh라 할 때 pos->next[nowCh]가 가르키는 값이 존재하지 않는다면, 즉, 아직 메모리가 alloc이 되지 않았다면 new를 통해 pos->next[nowCh]에 메모리를 alloc해주고


pos위치를 pos = pos->next[nowCh]로 옮겨준다.


그렇게 계속 넘어가다가 마지막으로 pos->isEnd = true를 통해 단어의 끝에 isEnd를 넣어준다면 Trie를 반복문으로 형성 할 수 있다.





** search함수를 이용하면 Trie를 이용하여 어떻게 단어를 구성하고 있는지 확인 할 수 있다. **








반응형

'Applied > 자료구조' 카테고리의 다른 글

해싱 기법 소스 코드(No STL)  (0) 2019.04.01
정적 할당을 이용한 Trie  (2) 2019.03.29
힙(Heap) 자료구조  (4) 2018.03.04
[STL] deque 구현  (2) 2018.02.28
[STL] list 구현  (2) 2018.02.28