题意:问你主串有几种模式串。但是所有串都是加密的,先解码。解码过程为:先把串按照他给的映射表变成6位数二进制数,然后首尾衔接变成二进制长串,再8位8位取变成新的数,不够的补0。因为最多可能到255,所以不能用char存,要用int。
思路:模拟乱搞一下,加个板子完事。
代码:
#include
#include
#include
struct Aho{
struct state{
int next[260];
int fail, cnt;
}node[maxn];
int size;
queue
void init(){
size = 0;
newtrie();
while(!q.empty()) q.pop();
}
int newtrie(){
memset(node\[size\].next, 0, sizeof(node\[size\].next));
node\[size\].cnt = node\[size\].fail = 0;
return size++;
}
void insert(int s\[\], int len, int id){
int now = 0;
for(int i = 0; i < len; i++){
int c = s\[i\];
if(node\[now\].next\[c\] == 0){
node\[now\].next\[c\] = newtrie();
}
now = node\[now\].next\[c\];
}
node\[now\].cnt = id;
}
void build(){
node\[0\].fail = -1;
q.push(0);
while(!q.empty()){
int u = q.front();
q.pop();
for(int i = 0; i < 260; i++){
if(node\[u\].next\[i\]){
if(u == 0) node\[node\[u\].next\[i\]\].fail = 0;
else{
int v = node\[u\].fail;
while(v != -1){
if(node\[v\].next\[i\]){
node\[node\[u\].next\[i\]\].fail = node\[v\].next\[i\];
break;
}
v = node\[v\].fail;
}
if(v == -1) node\[node\[u\].next\[i\]\].fail = 0;
}
q.push(node\[u\].next\[i\]);
}
}
}
}
set<int> res;
void get(int u){ //匹配规则
while(u){
if(node\[u\].cnt) res.insert(node\[u\].cnt);
u = node\[u\].fail;
}
}
int match(int s\[\], int len){
res.clear();
int ret = 0, now = 0;
for(int i = 0; i < len; i++){
int c = s\[i\];
if(node\[now\].next\[c\]){
now = node\[now\].next\[c\];
}
else{
int p = node\[now\].fail;
while(p != -1 && node\[p\].next\[c\] == 0){
p = node\[p\].fail;
}
if(p == -1) now = 0;
else now = node\[p\].next\[c\];
}
get(now);
}
return res.size();
}
}ac;
int main(){
init();
int n;
while(~scanf("%d", &n)){
ac.init();
for(int i = 1; i <= n; i++){
scanf("%s", s);
int len = sp();
ac.insert(now, len, i);
}
ac.build();
int m;
scanf("%d", &m);
while(m--){
scanf("%s", s);
int len = sp();
printf("%d\n", ac.match(now, len));
}
printf("\n");
}
return 0;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章