单词替换(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();
}
}
时间: 2024-10-07 05:07:02