bzoj3940&&bzoj3942 Ac自动机||kpm算法

方法就是维护一个动态栈 记录栈的每一位匹配到串的哪一位的编号 第一道kmp第二道ac自动机 自己理会
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=1000055;
char stack[M],s[M],t[M],f[M],next[M];
int len,top;
void getfail(){
    for(int i=1;i<len;i++){
        int j=f[i];
        while(j&&t[i]!=t[j]) j=f[j];
        f[i+1]=(t[i]==t[j]?j+1:0);
    }
}
int main()
{
    scanf("%s %s",s,t);
    int L=strlen(s); len=strlen(t); getfail(); 
    for(int i=0;i<L;i++){
        stack[++top]=s[i];
        int j=next[top-1];
        while(j&&t[j]!=stack[top]) j=f[j];
        if(t[j]==stack[top]) j++;
        next[top]=j;
        if(j==len) top-=len;
    }
    for(int i=1;i<=top;i++) printf("%c",stack[i]);
    return 0;
}
View Code
//同bzoj3942 
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int size=27,M=100055;
char s[M],T[M],stack[M];
int next[M],top,n;
struct node{
    int sum,a[M][27],last[M],fail[M],val[M];
    int id(char s) {return s-'a'+1;}
    void insert(char s[]){
        int k=0,L=strlen(s);
        for(int i=0;i<L;i++){
            int now=id(s[i]);
            if(!a[k][now]) a[k][now]=++sum;
            k=a[k][now];
        }
        val[k]=L;
    }
    void getfail(){
        int q[M],k=0,head=0,tail=0;
        for(int i=1;i<=26;i++){
            int now=a[0][i];
            if(now) q[tail++]=now;
        }
        while(head!=tail){
            int x=q[head++];
            for(int i=1;i<=26;i++){
                int now=a[x][i];
                if(!now) { a[x][i]=a[fail[x]][i];continue;}
                q[tail++]=now;
                fail[now]=a[fail[x]][i];
                last[now]=val[fail[now]]?fail[now]:last[fail[now]];
            }
        }
    }
    void Ac_boy(){
        int now=0,L=strlen(T);
        for(int i=0;i<L;i++){
            int d=id(T[i]);
            stack[top]=T[i];
            now=a[now][d];
            next[top]=now;
            if(val[now]) top-=val[now],now=next[top];
            else if(last[now]) top-=val[last[now]],now=next[top];
            top++;
        }
    }
}node;
int main()
{
    scanf("%s",T);
    int n; scanf("%d",&n);
    while(n--) scanf("%s",s),node.insert(s);
    node.getfail(); node.Ac_boy();
    for(int i=0;i<top;i++) putchar(stack[i]);
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/lyzuikeai/p/6894016.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值