B3942 Censoring

爆炸入口

有一个S串和一个T串,长度均小于1,000,000,设当前串为U串,然后从前往后枚举S串一个字符一个字符往U串里添加,若U串后缀为T,则去掉这个后缀继续流程。

这道题确乎是个很好的联系kmp的题目

结合了栈的思想。通过栈保留匹配时的失配指针的位置,达到分段删除的效果,即可以通过删去中间若干个T串,使得被删去左右两端可以拼成T。

同时也因为栈,使得我们在输出的更加方便。结束时,在栈中的元素一定是无法删除的元素。而且是有序的(输入顺序,从下标小的开始),直接输出即可以。


怎么使用栈呢?

对于每一个匹配串中的字符。我们一一将其入栈,然后保留以当前元素为结束kmp的失配指针,方便我们拼接。然后继续和普通的kmp一样匹配。

每次从栈顶拿一个元素出来(一定是栈),根据已经保留的失配指针继续匹配。

匹配到时,就立马退栈。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int manx=1000100;
int stack[manx],top;
int f[manx],fail[manx];
char a[manx],b[manx];
int main()
{
    int n,m;
    scanf("%s%s",a,b);
    n=strlen(a),m=strlen(b);
    int k=0;
    for(int i=1;i<m;i++)
    {
        while(k&&b[i]!=b[k])    k=fail[k];
        if(b[i]==b[k])  fail[i+1]=++k;//处理失配指针
    }
    for(int i=0;i<n;i++)//一样的匹配
    {
        k=f[stack[top]];//每次从栈顶拿一个元素,因为第一个元素是0,所以说我就没有写将0入栈
        while(k&&a[i]!=b[k])    k=fail[k];//跳失配
        if(a[i]==b[k])  ++k;
        if(k==m)    top-=(m-1);//匹配到时,退栈,一定要处理好退栈的元素个数,我这里i还没有入栈,所以只退栈m-1个元素
        else    f[i]=k,stack[++top]=i;//保留fail,进栈
    }
    for(int i=1;i<=top;i++)
        printf("%c",a[stack[i]]);//输出
}

转载于:https://www.cnblogs.com/Lance1ot/p/9224173.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值