SCU - 4438 (KMP)

SCU - 4438 (KMP)

Censor

frog is now a editor to censor so-called sensitive words (敏感词).

She has a long text pp. Her job is relatively simple – just to find the first occurence of sensitive word ww and remove it.

frog repeats over and over again. Help her do the tedious work.

Input

The input consists of multiple tests. For each test:

The first line contains 11 string ww. The second line contains 11 string pp.

(1≤length of w,p≤5⋅1061≤length of w,p≤5⋅106, w,pw,p consists of only lowercase letter)

Output

For each test, write 11 string which denotes the censored text.

Sample Input

    abc
    aaabcbc
    b
    bbb
    abc
    ab

Sample Output

    a
    
    ab

题意:

​ 一个模板串tt,一个文本串ss,我们从文本穿ss中删除模板串tt,重复这一过程,直至文本串中不包含模板串 。输出最后的文本串。

思路:

​ 前置知识:KMP

i i i 指针指文本串将要匹配的位置,j 指针指模式串将要匹配的位置

​ kmp用来文本串与模板串匹配,如果匹配成功怎么办? i i i指针回退?不,我们可以维护另一个数组,作为匹配过程中的数组;每次文本串的 i i i 指针往后移动时,就将新的字符加入一个像栈一样的数组;如果当前是完全匹配模板串 t t tt tt,那么就将先从栈中弹出模板串 t t tt tt,再将新的字符加入栈即可。并且将 j j j指针指向栈中上次同样位置即可。

这样每次 i i i 指针文本串将要匹配的字符, j j j 指针指向模板串将要匹配的字符,栈中的字符是更新后的字符。

​ 这个过程就像模拟题目的操作一样。每次字符串向后移动,如果完全匹配,则删除字符串,并且重置 j j j指针。继续向后遍历字符

#include
#define mset(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
char t[5000010],s[5000010],ans[50000010];
int net[5222010],maxj[5222210];
void getNext(const char s[],int ls,int net[])
{
    net[0]=-1;
    int j=0,k=-1;
    while(j<ls){
        if(k==-1||s[j]==s[k]) net[++j]=++k;
        else k=net[k];
    }
}
void solve(char tt[],char ss[])
{
    int lt=strlen(tt),ls=strlen(ss);
    int i=0,j=0,k=0;
    getNext(tt,lt,net);
    /*
    i j  maxj[] ans[]
    */
    ans[0]=s[0];
    maxj[0]=0;
    while(i<ls)
    {
        while(j!=-1&&ans[k]!=tt[j]) j=net[j];
        ++k,++i;++j;
        if(j>=lt){
            k-=lt;
            j=maxj[k];
        }
        ans[k]=ss[i];
        maxj[k]=j;
    }
}
int main(){
    while(cin>>t>>s)
    {
        solve(t,s);
        cout<<ans<<endl;
    }
}

你可能感兴趣的:(#,KMP)