Censor KMP算法

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

没想到啊,还是对KMP算法不太了解,用数组模拟栈,匹配完后,用下标index -= m,相当于就删去了,和之前的合并,用一个数组记录一下之前每个index分别对应敏感词的哪个,删去之后,将敏感词下标 j = tmp[index],就从合并过去了;结合代码理解一下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
#define mp make_pair
#define pb push_back
#define fi first
#define se second
const int MAXN = 5e6 + 5;
int Next[MAXN],tmp[MAXN];

void getNext(char s[])
{
    memset(Next,-1,sizeof(Next));
    int i,j;
    int n = strlen(s);
    j = -1;
    for(i = 0;i < n - 1;++i)
    {
        //i,j都表示当前已经匹配过的字符,而j+1与i+1是未匹配过的字符
        while(j >= 0 && s[j+1] != s[i+1]){
            j = Next[j];
        }
        //跳出循环有两种情况,回溯到s[0]也没匹配到,或者未到达s[0]是匹配到了
        if(s[j+1] == s[i+1]) j++;
        //再次确认上面跳出循环的情况,并对j进行操作。
        Next[i+1] = j;
    }
}

char st[MAXN];
//s1是主串,s2是匹配串
int Search(char s1[],char s2[])
{
    getNext(s2);
    int i;
    int n = strlen(s1);
    int m = strlen(s2);
    int j = -1;
    int index = 0;
    //i代表在s1里的下标,j代表s2里的下标
    for(i = 0;i < n;++i)
    {
        st[index++] = s1[i];  //存储匹配失败的字符串,通过后面index -= m来进行删除操作
        while(j >= 0 && s1[i] != s2[j + 1])
        {
            j = Next[j];
        }
        //跳出循环有两种情况:要从头匹配或者是匹配到了
        if(s1[i] == s2[j + 1])
            j++;
        tmp[index] = j; //记录当前index所匹配到的敏感词的下标,完成删除后的合并操作
        //匹配到了,j后移
        if(j == m - 1)
        {
            index -= m;
            j = tmp[index];
        }
    }
    return index;
}

char str1[MAXN],str2[MAXN];

int main()
{
    while(~scanf("%s%s",str1,str2)){
        st[Search(str2,str1)] = '\0';
        printf("%s\n",st);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值