字典树

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
#include<iostream>
#include<string>
using namespace std;
struct Node//结点
{
bool isEnd;//是否是最后一个结点,判断是否完全匹配
Node*son[26];//子结点,一共26个字母
char val;//当前结点值
long long num;//当前结点与父结点的距离
Node(char x='a'):isEnd(false),num(0)
{
for(int i=0;i<26;i++)
{
son[i]=NULL;
}
val=x;
}
~Node()//析构函数
{
for(int i=0;i<26;i++)
{
if(son[i])
delete son[i];
}
}
};
struct Tree//树
{
Node*root;
Tree()
{
root=new Node();
}
};
Tree head;//头,字典树头节点不包含信息
void insert_str(string s)//字符串为空,返回
{
if(s.size()==0)
{
return;
}
Node*temp=head.root;
for(int i=0;i<s.size();i++)
{
int pos=s[i]-'a';
if(temp->son[i]==NULL)//如果不存在,那么开辟空间
{
temp->son[i]=new Node(s[i]);
}
temp=temp->son[i];//存在,继续遍历
}
temp->isEnd=true;//插入的最后一个字符,标记
}
bool query(string s)
{
if(!s.size())
return false;
Node*temp=head.root;
for(int i=0;i<s.size();i++)
{
int pos=s[i]-'a';
if(temp->son[i]==NULL)//如果不存在,不匹配
{
return false;
}
temp=temp->son[i];//存在,继续遍历
}
return temp->isEnd;//可能是部分匹配
}
int main()
{
long long T;
cin>>T;
string s;
while(T--)//建树,插入字符串
{
cin>>s;
insert_str(s);
}
cin>>T;
while(T--)
{
cin>>s;
if(query(s))
{
cout<<"existn";
}
else
{
cout<<"no existn";
}
}
}

字典树本质是一种文本快速匹配算法