tir树算是一种以空间换取时间的存取数据方式,AC自动机的一种简单形式,两个主要的函数:插入序列与查找序列:
int cnt, nex[1000000][26], exist[1000000];
void insert(string s){
int p = 0;
for(auto i:s){
int c = i - 'a';
if(!nex[p][c])
nex[p][c] = ++cnt;
p = nex[p][c];
}
exist[p] = 1;
}
int find(string s){
int p=0;
for(auto i:s){
int c = i - 'a';
if(!nex[p][c])
return 0;
p = nex[p][c];
}
if(exist[p]==1)
{
exist[p] = 2;
return 1;
}
return 2;
}
cnt记录节点个数
nex记录数据
exist记录节点的数据状态
看代码就可以理解大意:
- insert过程先传入一个字符串,从头到尾遍历字符,存在的话p更新序号,不存在的话创建一个对应的点并且更新序号,最后在尾部声明节点状态
- find传入一个字符串从头到尾遍历如果没有则不存在数据,如果有查看最后字母节点是否状态为结尾,经过一次查询会改变状态
/*
* @Descripttion:
* @Author: ssw
* @Date: 2021-01-15 23:20:31
* @LastEditors: ssw
* @LastEditTime: 2021-01-15 23:40:33
*/
#include<bits/stdc++.h>
using namespace std;
int cnt, nex[1000000][26], n, m, exist[1000000];
void insert(string s){
int p = 0;
for(auto i:s){
int c = i - 'a';
if(!nex[p][c])
nex[p][c] = ++cnt;
p = nex[p][c];
}
exist[p] = 1;
}
int find(string s){
int p=0;
for(auto i:s){
int c = i - 'a';
if(!nex[p][c])
return 0;
p = nex[p][c];
}
if(exist[p]==1)
{
exist[p] = 2;
return 1;
}
return 2;
}
int main()
{
string s;
cin >> n;
while(n--){
cin >> s;
insert(s);
}
cin >> m;
while(m--){
cin >> s;
int flag = find(s);
if(flag==0)
cout << "WRONG" << endl;
else if(flag==1)
cout << "OK" << endl;
else
cout << "REPEAT" << endl;
}
return 0;
}