思路:AC自动机
分析:
1 题目输入n个字符串,然后输入m个源码串。对每一个源码串要求找到里面包含了几个字符串,如果有包含则按照从小到大输出字符串的编号,否则不输出。
2 典型的ac自动机。首先利用n个字符串建立字典树并且在字典树上面求出失配指针。然后对每一个输入的源码串进行find()即可。
3 ASCLL字符表可见字符(可打印字符)从32~126
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF 0x3f3f3f3f /*这个值可以用来初始化数组*/
#define MAXN 100010
#define N 110
int n , m , sum , cnt;
int ans[3];
struct Node{
Node* next;
Node* child[N];
int number;/*标记编号*/
int pos;/*标记有没有被用过*/
};
Node node[MAXN];
Node *root;
queue<Node*>q;
Node* newNode(){
node[cnt].next = NULL;
node[cnt].number = 0;
node[cnt].pos = 0;
for(int i = 0 ; i < N ; i++)
node[cnt].child[i] = NULL;
return &node[cnt++];
}
void insert(char *str , int x){
Node *p = root;
int len = strlen(str);
for(int i = 0 ; i < len ; i++){
int num = str[i]-32;
if(p->child[num] == NULL)
p->child[num] = newNode();
p = p->child[num];
}
p->number = x;
}
void getNext(){
while(!q.empty())
q.pop();
q.push(root);
root->next = NULL;
while(!q.empty()){
Node *p = q.front();
q.pop();
for(int i = 0 ; i < N ; i++){
if(p->child[i]){
q.push(p->child[i]);
Node *tmp = p->next;
while(tmp){
if(tmp->child[i]){
p->child[i]->next = tmp->child[i];
break;
}
tmp = tmp->next;
}
if(tmp == NULL)
p->child[i]->next = root;
}
}
}
}
void find(char *str , int x){
int len = strlen(str);
int pos = 0;
Node *p = root;
for(int i = 0 ; i < len ; i++){
int num = str[i]-32;
while(p->child[num] == NULL && p != root)
p = p->next;
if(p->child[num]){
p = p->child[num];
Node *tmp = p;
while(tmp){
if(tmp->number){
if(tmp->pos != x){/*如果没有被用过那么保存到ans数组里面*/
ans[pos++] = tmp->number;
tmp->pos++;
}
}
tmp = tmp->next;
}
}
}
}
int main(){
char str[MAXN];
while(scanf("%d%*c" , &n) != EOF){
sum = cnt = 0;
root = newNode();
for(int i = 1 ; i <= n ; i++){
gets(str);
insert(str , i);
}
getNext();
scanf("%d%*c" , &m);
for(int i = 1 ; i <= m ; i++){
gets(str);
memset(ans , INF , sizeof(ans));/*初始化为INF*/
find(str , i);
if(ans[0] == INF)
continue;
printf("web %d:" , i);
sort(ans , ans+3);/*排序*/
for(int j = 0 ; j < 3 ; j++){
if(ans[j] == INF)
break;
printf(" %d" , ans[j]);
}
printf("\n");
sum++;
}
printf("total: %d\n" , sum);
}
return 0;
}