源代码:
#include<iostream>
using namespace std;
string s;
int n,num(0);
struct treetype
{
char t; //用于节点储存字符。
bool over; //用于标记是否为此字符串的终结。
int next,deep,same; //分别用于标记此节点的下一层节点、所在层数、下一个兄弟节点。
}tree[100001];
void x1(string s) //插入。
{
int m=s.size()-1,k(0); //注意,在C++中,字符串以开头为0的、字符数组的形式存在。
while (1)
{
if (tree[k].deep==m) //此字符串插入完毕。
{
tree[k].over=true;
break;
}
if (tree[k].next==-1) //此节点没有儿子。
{
num++; //用于增加节点编号。
tree[num].deep=tree[k].deep+1;
tree[num].t=s[tree[num].deep];
tree[num].over=false;
tree[num].same=-1; //初始化兄弟。
tree[num].next=-1; //初始化儿子。
tree[k].next=num; //标记儿子。
k=num; //编号叠加。
}
else //此节点有儿子。
{
k=tree[k].next; //注意,不必担心父亲。
while (tree[k].t!=s[tree[k].deep]&&tree[k].same!=-1)
k=tree[k].same; //依次对兄弟进行匹配。
if (tree[k].t!=s[tree[k].deep])
{
num++; //同理于上,同父同层匹配。
tree[num].deep=tree[k].deep;
tree[num].t=s[tree[num].deep];
tree[num].over=false;
tree[num].same=-1;
tree[num].next=-1;
tree[k].same=num; //标记兄弟。
k=num;
}
}
}
}
bool x2(string s) //查找。
{
int m=s.size()-1,k(0);
while (1)
{
if (tree[k].deep==m&&tree[k].over) //匹配成功。
return true;
if (tree[k].next==-1) //没有下一层却并未退出,故匹配不成功。
return false;
k=tree[k].next; //注意,不必担心父亲。
while (tree[k].t!=s[tree[k].deep]&&tree[k].same!=-1)
k=tree[k].same; //进行兄弟匹配。
if (tree[k].t!=s[tree[k].deep]) //兄弟没有匹配成功。
return false;
}
}
int main()
{
tree[0].deep=0; //初始化根节点。
tree[0].over=false;
tree[0].next=-1;
tree[0].same=-1;
cin>>n;
for (int a=1;a<=n;a++)
{
int t;
cin>>t;
cin>>s; //似乎并不能使用getline()。
s=" "+s; //注意,在C++中,字符串以开头为0的、字符数组的形式存在。
if (t==1)
x1(s);
if (t==2)
if (x2(s))
printf("Yes\n");
else
printf("No\n");
}
return 0;
}