SOJ 4438 Censor (字符串,kmp,hash,经典)

  • 题意:两个字符串w, p。 执行以下操作,1.如果p中含有w,将第一个遇到的w删除,剩下的连接起来。2.如果p中还有w重复1,否则输出处理后的字符串。
  • 思路:可以用一个栈来处理这个问题,其中匹配可以采用kmp算法,也可以用hash。
  • 代码:
//kmp
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5000000 + 5;
char w[maxn], p[maxn];
char ans[maxn];
int next[maxn];
void getnext(char *str, int next[])
{
    int len = strlen(str);
    next[0] = -1;
    int j = 0, k = -1;
    while(j < len) {
        if(k == -1 || str[j] == str[k]) {
            j++; k++;
            if(str[j] == str[k]) {
                next[j] = next[k];
            } else {
                next[j] = k;
            }
        } else {
            k = next[k];
        }
    }
}

int main()
{
    while(scanf("%s%s", w, p) == 2) {
        //memset(ans, 0, sizeof(ans));
        getnext(w, next);
        stack<char> sta;
        stack<int> mt;
        int plen = strlen(p), wlen = strlen(w);
        int j = 0, k = 0;
        while(j < plen) {
            if(k == -1 || p[j] == w[k]) {
                j++; k++;
                sta.push(p[j-1]);
                mt.push(k);
                if(k == wlen) {
                    for(int i = 0; i < wlen; i++) {
                        sta.pop();
                        mt.pop();
                    }
                    if(mt.empty()) {
                        k = 0;
                    }
                    else k = mt.top();
                }
            } else {
                k = next[k];
            }
        }
        int i = sta.size() - 1;
        ans[i+1] = '\0';
        while(!sta.empty()) {
            ans[i--] = sta.top();
            sta.pop();
        }
        printf("%s\n", ans);
    }
    return 0;
}
//hash
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5000000 + 5;
const int seed = 1331;
typedef unsigned long long  ull;
char w[maxn], p[maxn];
char ans[maxn];
ull _hash[maxn];
int main()
{
    while(~scanf("%s%s", w, p)) {
        ull mhash = 0;
        unsigned int wlen = strlen(w), plen = strlen(p);
        ull k = 1;
        for(int i = 0; i < wlen; i++) {
            mhash = mhash*seed + w[i];
            k *= seed;
        }

        stack<char> sta;
        int i = 0, len = 1;
        _hash[0] = 0;
        for(; i < plen; i++, len++) {
            _hash[len] = _hash[len - 1] * seed + p[i];
            sta.push(p[i]);
            if(len >= wlen) {
                if(_hash[len] - _hash[len - wlen]*k == mhash) {
                    for(int j = 0; j < wlen; j++) {
                        sta.pop();
                    }
                    len = len - wlen ;
                }
            }
        }

        int j = sta.size();
        ans[j--] = '\0';
        while(!sta.empty()) {
            ans[j--] = sta.top();
            sta.pop();
        }
        printf("%s\n", ans);
    }
    return 0;
}
    原文作者:KMP算法
    原文地址: https://blog.csdn.net/lxc779760807/article/details/48343833
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞