CQU 单词替换(KMP)

单词替换(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();
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章