-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathTiretree.h
More file actions
213 lines (187 loc) · 5.17 KB
/
Tiretree.h
File metadata and controls
213 lines (187 loc) · 5.17 KB
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#include <iostream>
using namespace std;
/* trie的节点类型 */
template <int Size> //Size为字符表的大小
struct trie_node
{
bool terminable; //当前节点是否可以作为字符串的结尾
int node; //子节点的个数
trie_node *child[Size]; //指向子节点指针
/* 构造函数 */
trie_node() : terminable(false), node(0) { memset(child, 0, sizeof(child)); }
};
/* trie */
template <int Size, typename Index> //Size为字符表的大小,Index为字符表的哈希函数
class trie
{
public:
/* 定义类型别名 */
typedef trie_node<Size> node_type;
typedef trie_node<Size>* link_type;
/* 构造函数 */
trie(Index i = Index()) : index(i){ }
/* 析构函数 */
~trie() { clear(); }
/* 清空 */
void clear()
{
clear_node(root);
for (int i = 0; i < Size; ++i)
root.child[i] = 0;
}
/* 插入字符串 */
template <typename Iterator>
void insert(Iterator begin, Iterator end)
{
link_type cur = &root; //当前节点设置为根节点
for (; begin != end; ++begin)
{
if (!cur->child[index[*begin]]) //若当前字符找不到匹配,则新建节点
{
cur->child[index[*begin]] = new node_type;
++cur->node; //当前节点的子节点数加一
}
cur = cur->child[index[*begin]]; //将当前节点设置为当前字符对应的子节点
}
cur->terminable = true; //设置存放最后一个字符的节点的可终止标志为真
}
/* 插入字符串,针对C风格字符串的重载版本 */
void insert(const char *str)
{
insert(str, str + strlen(str));
}
/* 查找字符串,算法和插入类似 */
template <typename Iterator>
bool find(Iterator begin, Iterator end)
{
link_type cur = &root;
for (; begin != end; ++begin)
{
if (!cur->child[index[*begin]])
return false;
cur = cur->child[index[*begin]];
}
return cur->terminable;
}
/* 查找字符串,针对C风格字符串的重载版本 */
bool find(const char *str)
{
return find(str, str + strlen(str));
}
/* 删除字符串 */
template <typename Iterator>
bool erase(Iterator begin, Iterator end)
{
bool result; //用于存放搜索结果
erase_node(begin, end, root, result);
return result;
}
/* 删除字符串,针对C风格字符串的重载版本 */
bool erase(char *str)
{
return erase(str, str + strlen(str));
}
/* 按字典序遍历单词树 */
template <typename Functor>
void traverse(Functor &execute = Functor())
{
visit_node(root, execute);
}
private:
/* 访问某结点及其子结点 */
template <typename Functor>
void visit_node(node_type cur, Functor &execute)
{
execute(cur);
for (int i = 0; i < Size; ++i)
{
if (cur.child[i] == 0) continue;
visit_node(*cur.child[i], execute);
}
}
/* 清除某个节点的所有子节点 */
void clear_node(node_type cur)
{
for (int i = 0; i < Size; ++i)
{
if (cur.child[i] == 0) continue;
clear_node(*cur.child[i]);
delete cur.child[i];
cur.child[i] = 0;
if (--cur.node == 0) break;
}
}
/* 边搜索边删除冗余节点,返回值用于向其父节点声明是否该删除该节点 */
template <typename Iterator>
bool erase_node(Iterator begin, Iterator end, node_type &cur, bool &result)
{
if (begin == end) //当到达字符串结尾:递归的终止条件
{
result = cur.terminable; //如果当前节点可以作为终止字符,那么结果为真
cur.terminable = false; //设置该节点为不可作为终止字符,即删除该字符串
return cur.node == 0; //若该节点为树叶,那么通知其父节点删除它
}
//当无法匹配当前字符时,将结果设为假并返回假,即通知其父节点不要删除它
if (cur.child[index[*begin]] == 0) return result = false;
//判断是否应该删除该子节点
else if (erase_node((++begin)--, end, *(cur.child[index[*begin]]), result))
{
delete cur.child[index[*begin]]; //删除该子节点
cur.child[index[*begin]] = 0; //子节点数减一
//若当前节点为树叶,那么通知其父节点删除它
if (--cur.node == 0 && cur.terminable == false) return true;
}
return false; //其他情况都返回假
}
/* 根节点 */
node_type root;
/* 将字符转换为索引的转换表或函数对象 */
Index index;
};
//index function object
class IndexClass
{
public:
int operator[](const char key)
{
if (key >= '0'&&key <= '9')
{
return key - '0';
}
else if (key>='a'&&key<='f')
{
return key - 'a' + 10;
}
else
{
return key - 'A' + 10;
}
}
};
/*
int main()
{
trie<26,IndexClass> t;
t.insert("tree");
t.insert("tea");
t.insert("A");
t.insert("ABC");
if(t.find("tree"))
cout<<"find tree"<<endl;
else
cout<<"not find tree"<<endl;
if(t.find("tre"))
cout<<"find tre"<<endl;
else
cout<<"not find tre"<<endl;
if(t.erase("tree"))
cout<<"delete tree"<<endl;
else
cout<<"not find tree"<<endl;
if(t.find("tree"))
cout<<"find tree"<<endl;
else
cout<<"not find tree"<<endl;
return 0;
}
*/