BZOJ_3942_[Usaco2015 Feb]Censoring_KMP
Description
有一个S串和一个T串,长度均小于1,000,000,设当前串为U串,然后从前往后枚举S串一个字符一个字符往U串里添加,若U串后缀为T,则去掉这个后缀继续流程。
Input
The first line will contain S. The second line will contain T. The length of T will be at most that of S, and all characters of S and T will be lower-case alphabet characters (in the range a..z).
Output
The string S after all deletions are complete. It is guaranteed that S will not become empty during the deletion process.
Sample Input
whatthemomooofun
moo
moo
Sample Output
whatthefun
用一个栈来记录当前匹配到那个字符和那个字符在哪个位置。
然后KMP每次跳nxt即可。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 1000050
int nxt[N],ls,lw,a[N],pos[N];
char s[N],w[N];
void get_nxt() {
int i,j=0;
for(i=2;i<=lw;i++) {
while(j&&w[j+1]!=w[i]) j=nxt[j];
nxt[i]=(w[j+1]==w[i])?++j:0;
}
}
void work() {
int i,j,top=0;
for(i=1;i<=ls;i++) {
j=pos[top];
a[++top]=s[i];
while(j&&w[j+1]!=s[i]) j=nxt[j];
if(w[j+1]==s[i]) j++;
if(j==lw) {
top-=lw;
}else pos[top]=j;
}
for(i=1;i<=top;i++) printf("%c",a[i]);
}
int main() {
scanf("%s%s",s+1,w+1);
ls=strlen(s+1); lw=strlen(w+1);
get_nxt();
work();
}