Censor SCU - 4438 (KMP)

本文介绍如何使用KMP算法高效地从文本中移除所谓的敏感词。通过一个具体的编程实例,详细阐述了KMP算法的思想及其实现过程,包括如何构建模式串的前缀表以及如何在主串中定位并移除模式串。

题目来源:

https://vjudge.net/contest/297070#problem/C

http://acm.scu.edu.cn/soj/problem.action?id=4438

Censor

frog is now a editor to censor so-called sensitive words (敏感词).

She has a long text pp. Her job is relatively simple -- just to find the first occurence of sensitive word ww and remove it.

frog repeats over and over again. Help her do the tedious work.

Input

The input consists of multiple tests. For each test:

The first line contains 11 string ww. The second line contains 11 string pp.

(1≤length of w,p≤5⋅1061≤length of w,p≤5⋅106, w,pw,p consists of only lowercase letter)

Output

For each test, write 11 string which denotes the censored text.

Sample Input

abc
aaabcbc
b
bbb
abc
ab

Sample Output

a
   
ab

题意:给一个模式串和一个主串,要求从主串中删除第一个模式串,然后拼接,继续删除直到不能删除输出最后的串

 比赛时候我上去就用了java但是tl(题目没给出时间空间限制)后来队友用的队列,个人感觉实现不了,最终还是没能实现,这时候我想到了KMP算法于是花了一个多小时开始琢磨板子,理解了一点改了一下,感觉没有一点问题,队友给了我半个小时,我打完之后过不了样例,我就好慌,,,赛后一看找到一个网上的ac代码和我思路一样,都是用到KMP算法思想,我一看,发现我主串和模式串好多地方搞混了QAQ...

思路:用一个数组pre记录主串中当前所指字符与模式串相匹配字符的长度。KMP思想,当主串中出现完整的模式串时,j跳到模式串pre[k-len1]的位置接着与主串i所指的下一个字符比较

参考代码:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;
const int N=5e6+5;
char s1[N],s2[N],ans[N];
int pre[N],len1,len2,Next[N];
using namespace std;
void pre_kmp()
{
    int i=0,j=-1;
    Next[0]=-1;
    while(i<len1)
    {
        if(j==-1 || s1[i]==s1[j])
        {
            i++;
            j++;
            Next[i]=j;
        }
        else
            j=Next[j];
    }
}
int main()
{
    while(~scanf("%s %s",s1,s2))//s1 模式串,s2 主串
    {
        len1= strlen(s1);
        len2= strlen(s2);
        pre_kmp();
        int i=0,j=0,k=0;
        while(i < len2)
        {
            ans[k]=s2[i];
            while(j!=-1 && ans[k]!=s1[j])
                j=Next[j];
            i++;
            j++;
            pre[k++]=j;//记录匹配到k位置时对应的成功匹配的模式串字符数目
            if(j==len1)
            {
                k-=len1;//相当于删除
                j=pre[k-1];//模式串跳转的位置
            }
        }
        ans[k] = '\0';
        printf("%s\n",ans);
    }
    return 0;
}

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nuoyanli

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值