弱校聯萌十一大決戰之強力熱身 C.Censor (KMP變形 好題)

_TCgogogo_發表於2015-10-08

C. Censor

Time Limit: 2000ms
Memory Limit: 65536KB

frog is now a editor to censor so-called sensitive words (敏感詞).
She has a long text p. Her job is relatively simple -- just to find the first occurence of sensitive word w 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 1 string w. The second line contains 1 string p.
(1length of w,p5106, w,p consists of only lowercase letter)

Output

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

Sample Input

abc
aaabcbc
b
bbb
abc
ab

Sample Output

a

ab


題目連結:http://www.bnuoj.com/v3/contest_show.php?cid=6865#problem/C


題目大意:一個子串,一個母串,要求刪除母串中的子串,刪完剩餘部分合並繼續刪,直到母串中不存在子串為止,輸出此時的母串

題目分析:不要求合併的話直接kmp即可,現在刪完要合併,其實只要記錄每次刪完,指向子串的指標回溯到哪個位置即可

#include <cstdio>
#include <cstring>
int const MAX = 5e6 + 5;
char s1[MAX], s2[MAX], ans[MAX];
int next[MAX], pos[MAX];
int l1, l2, cnt;

void get_next()
{
    int i = 0, j = -1;
    next[0] = -1;
    while(s2[i] != '\0')
    {
        if(j == -1 || s2[i] == s2[j])
        {
            i ++;
            j ++;
            if(s2[i] == s2[j])
                next[i] = next[j];
            else
                next[i] = j;
        }
        else
            j = next[j];
    }
}

void KMP()
{
    get_next();
    int i = 0, j = 0;
    cnt = 0;
    while(s1[i] != '\0')
    {
        ans[cnt] = s1[i ++];
        while(!(j == -1 || ans[cnt] == s2[j]))
            j = next[j];
        j ++;
        cnt ++;
        pos[cnt] = j;
        if(j == l2)
        {
            cnt -= l2;
            j = pos[cnt];
        }
    }
}

int main()
{
    while(scanf("%s %s", s2, s1) != EOF)
    {
        l1 = strlen(s1);
        l2 = strlen(s2);
        KMP();
        for(int i = 0; i < cnt; i++)
            printf("%c", ans[i]);
        printf("\n");
    }
}    


相關文章