字典(前缀)树,用来保存字符集合。
通过建树后 可以快速进行查询相关操作。
此树的特点在于信息在两个节点之间的边上,每条边是一个字符,当一条路径可以构成一个单词的时候,这条路径的最底端(不一定是叶子节点)将会被标记。
例如: 对 ab,abc,c,bd,cd,efg 进行建树
节点是粉色的表示当前从根到当前节点会构成完整的单词。
每个几点最多有26个孩子,因为有26个字母。
以下用数组进行建树及相关操作 其中的sz是每个节点的编号,
#include <iostream>
#include <string>
using namespace std;
#define MAX 10000
#define SIZE 30
class Trie {
private:
int val[MAX];
int sz; //节点编号
char ch[MAX][SIZE]; //ch[i][j] = k 节点i的第j个孩子的节点为k
public:
Trie() {
sz = 1;
memset(ch[0], 0, sizeof(ch[0]));
}
int idx(char c) {
return c - 'a';
}
void insert(string s, int v) {
int node = 0; //节点
int id;
for (int i = 0; i < s.size(); i++) {
id = idx(s[i]);
//这个节点不存在 需要创建
if (!ch[node][id]) {
//第node节点的第id个孩子为sz编号
ch[node][id] = sz;
memset(ch[node], 0, sizeof(ch[node]));
val[sz] = 0;
sz++;
}
node = ch[node][id];
}
//表示根到当前节点可以组成一个单词
val[node] = v;
}
//查询s是否存在于字典树中
bool find(string s) {
int node = 0;
int id;
int k; //当前节点的编号
for (int i = 0; i < s.size(); i++) {
id = idx(s[i]);
k = ch[node][id];
if (!ch[node][id] && !val[k])
return false;
else
node = ch[node][id];
}
if (val[k] == 1)
return true;
return false;
}
};
int main()
{
Trie trie;
int n = 2;
string s;
for (int i = 0; i < n; i++) {
cin >> s;
trie.insert(s, 1);
}
string t;
cin >> t;
cout << trie.find(t) << endl;
system("pause");
return 0;
}