标签:
源代码: #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; }
标签:
原文地址:http://www.cnblogs.com/koruko/p/5193611.html