hdu2896&&3065

题:http://acm.hdu.edu.cn/showproblem.php?pid=2896

分析:ac自动机模板

   注意细节,1、128个ascii码都要;

        2、只要关键码含有只输出一个编号就行

#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
#define pb push_back
const int M=501*201;
const int N=505;
int vis[N];
int n;
struct ac{
    int tot,root;
    int trie[M][130],end[M],fail[M];
    int newnode(){
        for(int i=0;i<130;i++){
            trie[tot][i]=-1;
        }
        end[tot]=0;
        tot++;
        return tot-1;
    }
    void init(){
        tot=0;
        root=newnode();
    }
    void insert(char *buf,int id){
        int now=root,len=strlen(buf);
        for(int i=0;i<len;i++){
            if(trie[now][buf[i]]==-1)
                trie[now][buf[i]]=newnode();
            now=trie[now][buf[i]];
        }
        end[now]=id;
    }
    void getfail(){
        queue<int>que;
        while(!que.empty())
            que.pop();
        fail[root]=root;
        for(int i=0;i<130;i++)
            if(trie[root][i]==-1)
                trie[root][i]=0;
            else{
                fail[trie[root][i]]=root;
                que.push(trie[root][i]);
            }
        while(!que.empty()){
            int now=que.front();
            que.pop();
            for(int i=0;i<130;i++){
                if(trie[now][i]!=-1){
                    fail[trie[now][i]]=trie[fail[now]][i];
                    que.push(trie[now][i]);
                }
                else
                    trie[now][i]=trie[fail[now]][i];
            }
        }
    }
    int query(char *buf){
        int len=strlen(buf);
        int ans=0;
        int now=root;
        for(int i=0;i<len;i++){
            now=trie[now][buf[i]];
            int tmp=now;
            while(tmp!=root){
                if(end[tmp]!=0){
                    vis[end[tmp]]=1;
                    ans++;
                }
                tmp=fail[tmp];
                    
            }
        }
        return ans;
    }
}AC;
char s1[10004],s[202];
int main(){
    while(~scanf("%d",&n)){
        AC.init();
        int ans=0;
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            AC.insert(s,i);
        }
        AC.getfail();
        int m;
        scanf("%d",&m);
        for(int i=1;i<=m;i++){
            memset(vis,0,sizeof(vis));
            scanf("%s",s1);
            if(AC.query(s1)>=1){
                printf("web %d:",i);
                for(int j=1;j<=n;j++)
                    if(vis[j])
                        printf(" %d",j);
                printf("
");
                ans++;
            }
        } 
        printf("total: %d
",ans);
    }
    return 0;
}
View Code

题:http://acm.hdu.edu.cn/showproblem.php?pid=3065

分析:只要将上题的vis改为技术数组即可

#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
#define pb push_back
const int M=51*1001;
const int N=1001;
char s[N][55],s1[2000002];
int n;
struct ac{
    int tot,root;
    int trie[M][130],end[M],fail[M],vis[M];
    int newnode(){
        for(int i=0;i<130;i++){
            trie[tot][i]=-1;
        }
        end[tot++]=0;
        return tot-1;
    }
    void init(){
        tot=0;
        root=newnode();
    }
    void insert(char *buf,int id){
        int len=strlen(buf);
        int now=root;
        for(int i=0;i<len;i++){
            if(trie[now][buf[i]]==-1)
                trie[now][buf[i]]=newnode();
            now=trie[now][buf[i]];
        }
        end[now]=id;
    }
    void getfail(){
        queue<int>que;
        while(!que.empty()){
            que.pop();
        }
        fail[root]=root;
        for(int i=0;i<130;i++){
            if(trie[root][i]==-1)
                trie[root][i]=root;
            else{
                fail[trie[root][i]]=root;
                que.push(trie[root][i]);
            }
        }
        while(!que.empty()){
            int now=que.front();
            que.pop();
            for(int i=0;i<130;i++){
                if(trie[now][i]!=-1){
                    fail[trie[now][i]]=trie[fail[now]][i];
                    que.push(trie[now][i]);
                }
                else
                    trie[now][i]=trie[fail[now]][i];
            }
        }
    }
    void query(char *buf){
        memset(vis,0,sizeof(vis));
        int len=strlen(buf);
        int now=root;
        for(int i=0;i<len;i++){
            now=trie[now][buf[i]];
            int tmp=now;
            while(tmp!=root){
                if(end[tmp]!=0)
                    vis[end[tmp]]++;
                tmp=fail[tmp];
            }
        }
        for(int i=1;i<=n;i++)
            if(vis[i]>0)
                printf("%s: %d
",s[i],vis[i]);
    }
}AC;
int main(){
    while(scanf("%d",&n)==1){
        AC.init();
        for(int i=1;i<=n;i++){
            scanf("%s",s[i]);
            AC.insert(s[i],i);
        }
        AC.getfail();
        
        scanf("%s",s1);
        AC.query(s1);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/starve/p/12266868.html