题目链接:Censor
题目大意:给你一个模式串和原串,现在要你去删除原串中出现的第一个模式串,然后在删除的原串中继续这种操作,直到找不到原串为止,输出最后的字符串
题目思路:首先字符串匹配,我们可以想到使用KMP,然后我们需要在KMP的思路上做一些操作,当匹配到一个完整的字符串时,我们需要将j指针移动到上一个没有匹配到的位置,然后进行继续的,然后我们可以用一个ans数组保存串,有删除的时候我们直接将left-l1就好,相当于删除了字符串
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e6+10;
int n,Next[maxn],fro[maxn];
char mo[maxn],str[maxn],ans[maxn];
void getNext(){
int i = 0,j = -1,len = strlen(mo);
while(i < len){
if(j == -1||mo[i] == mo[j]) Next[++i] = ++j;
else j = Next[j];
}
}
void kmp(){
int i = 0,j = 0,left = 0;
int l1 = strlen(mo);
int l2 = strlen(str);
while(i < l2){
ans[left] = str[i];
if(j == -1||mo[j] == str[i]){
i++;
j++;
left++;
fro[left] = j;
}
else j = Next[j];
if(j == l1){
left -= l1;
j = fro[left];
}
}
for(int i=0;i<left;i++)
printf("%c",ans[i]);
printf("\n");
}
int main(){
int n,m,k;
while(~scanf("%s%s",mo,str)){
Next[0] = -1;
getNext();
kmp();
}
return 0;
}