SCU - 4438 Censor 【字符串好题】

传送门
//题意:每次从第二个串中删去第一个串, 输出最后剩下的串.
//思路: 这道题是字符串一列比较经典的题目, 一般所有的求解字符串的题目都可以做. 我用的是KMP. 每次保存匹配到当前位成功匹配到了第一串目前匹配位置的前面的几个字符. 这样每次匹配到了一次第一个串后,k -= len, t = now[k-1] ,这样就又可以接着匹配了.

AC Code

/** @Cain*/
const int maxn = 5e6+5;
int cas=1;
char zc[maxn], pp[maxn];
int Next[maxn];

void getnext(char *s, int len) {
    int t1 = 0, t2;
    Next[0] = t2 = -1;
    while(t1 < len){
        if(t2 == -1 || s[t1] == s[t2])
            Next[++t1] = ++t2;
        else t2 = Next[t2];
    }
}
char pri[maxn];
int now[maxn];
void kmp(char *zc, char *pp, int len1, int len2) {
    int i = 0 ,t = 0, k = 0;
    while(iwhile (t != -1 && zc[i] != pp[t]) t = Next[t];
        i++; t++;
        now[k++] = t;  //记录匹配k位时对应的成功匹配到了的子串数目.
        //这样再下一轮减完时可以知道新的位置之前有多少位匹配到了.
        //这样才可以到达目的.
        if (t == len2) {
            k -= len2;
            t = now[k-1];
        }
    }
    pri[k] = 0;
}
void solve()
{
    while(~scanf("%s%s",pp,zc)){
        getnext(pp,strlen(pp));
        kmp(zc,pp,strlen(zc),strlen(pp));
        printf("%s\n",pri);
    }
}

你可能感兴趣的:(KMP/hash字符串问题)