题意:给定一个模式串和文本,要求删除所有模式串。可能删除后会形成新的模式串,必须全部删除。


思路1:kmp算法求得失配数组,用一个match数组记录文本串中第i字符和未删除的字符能匹配模式串的长度。这样每次删除字符串之后就不用再匹配,直接查询match数组即可。用栈模拟,自己实现的栈可以加快速度。

AC代码

#include <cstdio>
#include <cmath>
#include <cctype>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 5e6 + 5;

int fail[maxn]; //失配数组
int match[maxn];
char p[maxn], w[maxn], ans[maxn];

void getFail(char *s, int *fail, int n) {
    fail[0] = -1;
    for(int i = 1; i < n; ++i) {
        int j = fail[i-1];
        while(j != -1 && s[j+1] != s[i]) j = fail[j];
        if(s[j+1] == s[i]) fail[i] = j+1;
        else fail[i] = -1;
    }
}
int top;
int sta[maxn];
void kmp(char *p, char *w, int *fail) {
    int n = strlen(w), m = strlen(p);
    getFail(w, fail, n);

    top = 0;

    int now = -1;
    for(int i = 0; i < m; ++i) {
        ans[top] = p[i];
        while(now != -1 && w[now+1] != p[i]) now = fail[now];
        if(w[now+1] == p[i]) {
            now = now + 1;
        }
        match[i] = now;
        sta[++top] = i;
        //成功匹配w
        if(now == n-1) {
            top -= n;
            if(top == 0) now = -1;
            else now = match[sta[top]];
        }
    }
    ans[top] = '\0';
}
int main() {
    while(scanf("%s%s", w, p) == 2) {
        kmp(p, w, fail);
        printf("%s\n", ans);
    }
    return 0;
}

思路2:哈希技术真的好玄学。一直判断最后strlen(w)字符的哈是值是否和模式串的哈希一致,如果一致就删除。

#include <cstdio>
#include <cmath>
#include <cctype>
#include <bitset>
#include <algorithm>
#include <cstring>
#include <utility>
#include <string>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <queue>
#include <stack>
using namespace std;
#pragma comment(linker, "/STACK:1024000000,1024000000")
#define eps 1e-10
#define inf 0x3f3f3f3f
#define PI pair<int, int>
typedef long long LL;
const int maxn = 5e6 + 5;
const int seed = 100003;
LL bit[maxn];
char p[maxn], w[maxn], ans[maxn];
LL sta[maxn];
void getBit() {
    bit[0] = 1;
    for(int i = 1; i < maxn; ++i)
        bit[i] = bit[i-1]*seed;
}

LL getHash(char *s, int len) {
    LL res = 0;
    for(int i = 0; i < len; ++i)
        res = res*seed + s[i];
    return res;
}

void solve(char *p, char *w) {
    int n = strlen(w), m = strlen(p);
    LL goal = getHash(w, n); 

    //栈 top=0表示栈空
    int top = 0;
    sta[top] = 0;

    for(int i = 0; i < m; ++i) {
        ans[top] = p[i];
        LL res = sta[top] * seed + p[i];
        sta[top++] = res;
        if(top >= n && res - sta[top-n]*bit[n] == goal) {
            top -= n;
        }
    }

    ans[top] = '\0';
    printf("%s\n", ans);
}

int main() {
    getBit();
    while(scanf("%s%s", w, p) == 2) {
        solve(p, w);
    }
    return 0;
}

如有不当之处欢迎指出!

SCU 4438 Censor KMP/Hash的更多相关文章

  1. ACM: SCU 4438 Censor - KMP

     SCU 4438 Censor Time Limit:0MS     Memory Limit:0KB     64bit IO Format:%lld & %llu  Practice D ...

  2. SCU 4438 Censor|KMP变形题

    传送门 Censor frog is now a editor to censor so-called sensitive words (敏感词). She has a long text P. He ...

  3. SCU 4438 Censor(Hash)题解

    题意:找出字符串p中的w串删除,反复操作,直到找不到w,输出这个串 思路:哈希处理前缀和,如果值相同就删掉. 代码: #include<iostream> #include<algo ...

  4. SCU 4438 Censor(哈希+模拟栈)

    Censor frog is now a editor to censor so-called sensitive words (敏感词). She has a long text \(p\). He ...

  5. SCU 4438:Censor

    Censor frog is now a editor to censor so-called sensitive words (敏感词). She has a long text p . Her j ...

  6. Codeforces 1090J $kmp+hash+$二分

    题意 给出两个字符串\(s\)和\(t\),设\(S\)为\(s\)的任意一个非空前缀,\(T\)为\(t\)的任意一个非空前缀,问\(S+T\)有多少种不同的可能. Solution 看了一圈,感觉 ...

  7. Censor SCU - 4438

    frog is now a editor to censor so-called sensitive words (敏感词). She has a long text (p). Her job is ...

  8. 【BZOJ3940】【BZOJ3942】[Usaco2015 Feb]Censoring AC自动机/KMP/hash+栈

    [BZOJ3942][Usaco2015 Feb]Censoring Description Farmer John has purchased a subscription to Good Hoov ...

  9. Censor(KMP)

    Censor frog is now a editor to censor so-called sensitive words (敏感词). She has a long text pp. Her j ...

随机推荐

  1. git 签出(恢复)指定文件

    在项目开发中,偶尔会因为误删文件或其他原因需要从git仓库中恢复某些文件.此篇文章将介绍如何通过git从历史提交记录.分支记录恢复指定文件. 1. git checkout 说明:使用git chec ...

  2. scrapy_ItemLoader

    什么是Itemloader? 一种容器,实现直白高效字段提取 直接赋值取值的方式,会出现一下几个问题 代码量一多,各种css和xpath选择器,充斥整个代码逻辑,没有规则,不利于维护 对于一个字段的预 ...

  3. 创建一个离线优先,数据驱动的渐进式 Web 应用程序

    原文地址:Build an offline-first, data-driven PWA 译文出自:我的个人博客 概述 在本文中,您将学习如何使用 Workbox 和 IndexedDB 创建离线优先 ...

  4. Maven的Archetype简介

    Archetype,骨架的意思. 文章出处:http://m.blog.csdn.net/blog/FireOfStar/42526027 Archetype是什么? 简单的说,Archetype是M ...

  5. 流API--原始类型流

    到目前为止,我们已经将整型收集到了一个Stream<Integer>的流中,不过将每个整数包装成相应对象显然是一个低效的做法,对于其他的基本类型也是一样,我们前面说过jdk提供包装类已经自 ...

  6. java里程碑之泛型--擦除和转换

    在严格的泛型代码里,带泛型声明的类总应该带着泛型参数.但是为了和古老的java代码保持一致,也就是说为了向下兼容,也允许在使用带泛型声明的类时不指定实际的类型参数.如果没有为这个泛型类指定实际的参数类 ...

  7. 简述 Hibernate 和 JDBC 的区别、优缺点

    1.hibernate是一个开源的.采用面向对象的思想实现ORM映射框架,它对jdbc进行了一层封装,对于数据库的连接.关闭.数据的持久化(增删改查).事务的管理都进行了封装,使得程序开发的时候可以用 ...

  8. Python笔记001-----简介及常用的库

    1.Python是一种解释性语言,大部分代码要比编译型语言(如C++,java等)运行要慢点多.2.对于高并发,多线程的应用程序而言,Python并不是理想语言,python有全局解释器锁(Globa ...

  9. C#使用Redis

    一,引入dll 1.ServiceStack.Common.dll 2.ServiceStack.Interfaces.dll 3.ServiceStack.Redis.dll 4.ServiceSt ...

  10. python3,进程间的通信

    本文来源于python 3.5版本的官方文档 multiprocessing模块为进程间通信提供了两种方法: 1.进程队列queue The Queue class is a near clone o ...