php中文网 | cnphp.com

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 381|回复: 0

AC 自动机(C++ 实现)

[复制链接]

3138

主题

3148

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

UID
1
威望
0
积分
7946
贡献
0
注册时间
2021-4-14
最后登录
2024-11-21
在线时间
763 小时
QQ
发表于 2022-10-2 19:11:44 | 显示全部楼层 |阅读模式
[mw_shl_code=c,true]#include<bits/stdc++.h>
using namespace std;
const int maxN(15e1),maxL(7e1),maxS(26);
int n;
string s[maxN+5],t;
struct AC_automaton{
        int cnt,tree[maxN*maxL+5][maxS+5],end[maxN*maxL+5],frm[maxN*maxL+5],fail[maxN*maxL+5],vistot[maxN*maxL+5],maxvistot;
        void init(){
                cnt=0,memset(tree,0,sizeof(tree)),memset(end,0,sizeof(end)),
                memset(frm,0,sizeof(frm)),memset(fail,0,sizeof(fail)),
                memset(vistot,0,sizeof(vistot)),maxvistot=0;
        }
        void insert(string s,int from){
                int u(0);
                for(int i(0);i<s.size();++i){
                        int c(s-'a'+1);
                        if(!tree[c])tree[c]=++cnt;u=tree[c];
                }
                ++end,frm=from;
        }
        void Get_fail(){
                queue<int>q;
                for(int i(1);i<=maxS;++i)if(tree[0])fail[tree[0]]=0,q.push(tree[0]);
                while(q.size()){
                        int u(q.front());q.pop();
                        for(int i(1);i<=maxS;++i){
                                int v(tree);
                                if(v)fail[v]=tree[fail],q.push(v);
                                else tree=tree[fail];
                        }
                }
        }
        void query(string t){
                int u(0);
                for(int i(0);i<t.size();++i){
                        u=tree[t-'a'+1];
                        for(int v(u);v;v=fail[v])if(frm[v])++vistot[frm[v]],maxvistot=max(maxvistot,vistot[frm[v]]);
                }
                printf("%d\n",maxvistot);
                for(int i(1);i<=cnt;++i)
                        if(vistot[frm]==maxvistot){
                                for(int j(0);j<s[frm].size();++j)printf("%c",s[frm][j]);
                                puts("");
                        }
        }
}AhoC;
int main(){
        while(scanf("%d",&n)){
                if(!n)break;
                AhoC.init();
                for(int i(1);i<=n;++i)cin>>s,AhoC.insert(s,i);
                AhoC.Get_fail();
                cin>>t,AhoC.query(t);
        }
        return 0;
}[/mw_shl_code]

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|php中文网 | cnphp.com ( 赣ICP备2021002321号-2 )

GMT+8, 2024-11-22 03:42 , Processed in 0.788509 second(s), 37 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

申明:本站所有资源皆搜集自网络,相关版权归版权持有人所有,如有侵权,请电邮(fiorkn@foxmail.com)告之,本站会尽快删除。

快速回复 返回顶部 返回列表