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;
}