單詞替換(KMP)
Time Limit: 500 MS Memory Limit: 64000 K
Description
給出一個僅包含小寫字母的字符串s,和單詞A,B。把s中所有的出現過的A替換爲B。
Input
第一行一個數T(1<=T<=10),表示數據組數
每組數據三行,第一行爲s,第二行爲A,第三行爲B。所有字符串僅包含小寫字母
且長度小於5,000,000。
Output
每組數據輸出一行,替換後的字符串。
Sample Input
3
aaa
a
b
aaa
aa
b
ababa
aba
cd
Sample Output
bbb
ba
cdba
題意:
如上所示,就是一個裸的kmp嘛。。
分析:
在kmp基礎上加一個替換的工作。
在母串中找到一個子串時,標記下這個子串在母串中的起始位置。最後掃一遍母串,按序輸出,遇到標記則輸出B串。
代碼:
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=5e6+5;
int T,ans;
int nxt[maxn];
char s[maxn],A[maxn],B[maxn];
bool flag[maxn];
void kmp(){
int i,j,k,m,n,p;
n=strlen(s);m=strlen(A);
j=nxt[0]=-1;i=0;
while(i<m){
if(j==-1|| A[i]==A[j])
nxt[++i]=++j;
else j=nxt[j];
}
p=i=ans=0;
while(i<n && p<m){
if(s[i]==A[p] || p==-1){
p++;
i++;
}
else p=nxt[p];
if(p==m){
ans++;
p=nxt[p];
flag[i-m]=true;
}
}
// cout<<flag[0]<<endl;
for(int i=0;i<n;i++)
if(flag[i]) {printf("%s",B); i+=m-1;}
else printf("%c",s[i]);
printf("\n");
}
int main(){
freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--){
scanf("%s\n",s);
scanf("%s\n",A);
scanf("%s\n",B);
memset(flag,false,sizeof flag);
kmp();
}
}