Censor SCU - 4438 (字符串hash)

Censor SCU - 4438 (字符串hash)

题目描述

Censor
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.

(1≤length of w,p≤5⋅106, 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

题意

多组输入两个字符串(1<=长度<=5*1e6),字符串都由小写字母组成。要求删除第二个字符串的子串(这个子串等于第一个字符串)。
注:第一个字符串在被删去子串后,剩余部分继续连接在一起。
如第一组样例
abc
aaabcbc
过程:aaabcbc—->aabc—->a

思路

先用字符串hash出第一个字符串的值,再对第二个字符串hash,判断子串与第一个字符串长度相同时的hash值是否相同,若相同则删除(用栈维护的思想,移动下标即可,最后栈中的字符串即为答案)

AC代码

#include 

using namespace std;
typedef unsigned long long ll; //unsigned 定义的可以自动取模
const int maxn=5000010;
char s1[maxn],s2[maxn],ans[maxn];
const ll HASH=1e5+7;  //在hash中常用一个比较大的素数
int n,m;  //分别为两个字符串的长度
ll multi[maxn];  //用于hash的数组
ll st[maxn],sum;  
void init()  //预处理
{
    multi[0]=1;
    int i;
    for(i=1;i1]*HASH;
}
inline bool check(int pos)
{
    if(pos>=n){  //取长度为n的子串的hash值与第一个字符串的hash值比较
        if(st[pos]-st[pos-n]*multi[n]==sum)
            return true;
    }
    return false;
}
int main()
{
    init();
    while(scanf("%s %s",s1,s2)!=EOF){  //多组输入
        n=strlen(s1);
        m=strlen(s2);
        int i,j,top=0;
        sum=0;  //第一个字符串的hash值
        for(i=0;i//用预处理好的数组对第一个字符串进行hash
        }
        st[0]=0;
        for(i=0;i1]*HASH+s2[i];
            if(check(top))  //判断
                top-=n;     //移动下标,表示删除长度为n的子串
        }
        //printf("ans:");
        for(i=0;iprintf("%c",ans[i]);
        printf("\n");
    }
    return 0;
}
/*
abc
aaabcbc
b
bbb
abc
ab
*/

你可能感兴趣的:(字符串hash)