标签:
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();
    }
}标签:
原文地址:http://blog.csdn.net/zyd8888102/article/details/51340941