Scu4438 栈+哈希

6 篇文章 0 订阅
2 篇文章 0 订阅

题目描述

现在给定一个你很讨厌的字符串 A 和另外一个字符串 B,请删除在 B 中出现的所有 A。
请注意:有可能在删除一个 A 后导致新的 A 出现,此时请继续删除,直到没有 A。

输入格式

输入为多组数据,请处理到 EOF。
对于每组数据:
第一行为你很讨厌的字符串 A,第二行为另外一个字符串 B,均仅包括小写字母。
保证 A串 和 B串 的长度不超过 5000000 且 A、B 均不为空串。

输出格式

对于每组数据,输出一行,即完成删除后的字符串。

样例输入

abc
aaabcbc
b
bbb
abc
ab

样例输出

a

ab

样例解释

第一组数据的删除过程:
aaabcbc -> aa[abc]bc -> aabc -> a[abc] -> a
第二组数据的删除过程:
bbb -> [b]bb -> bb -> [b]b -> b -> [b] ->
第三组数据由于讨厌的字符串并没有出现,所以没有被删除任何一个部分。

思路:开始毫无思路,后来百度他人题解看到了别人的标签,栈,瞬间思路就来了,就像括号匹配一样,这个题目也可以这样做,只是判断是否匹配复杂度很高,这个时候就可以用到哈希,用O(1)的时间判断两个字符串是否匹配,所以总复杂度就是O(n)。

代码:

#include<bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define Max 5000005
const LL mod=1e9+7;
const ULL base=131;
const LL LL_MAX=9223372036854775807;
using namespace std;
ULL Hash[Max],p[Max];
char Stack[Max],a[Max],b[Max];
inline ULL getHashRange(int l,int r){
    return Hash[r]-Hash[l-1]*p[r-l+1];
}
void init(){
    p[0]=1;
    for(int i=1;i<Max;i++)
        p[i]=p[i-1]*base;
}
int main()
{
    init();
    while(scanf("%s%s",a+1,b+1)==2){
        memset(Stack,0,sizeof(Stack));
        int lena=strlen(a+1),lenb=strlen(b+1);
        ULL Hasha=0;
        for(int i=1;i<=lena;i++)
            Hasha=Hasha*base+a[i];
        int top=1;
        for(int i=1;i<=lenb;i++){
            Hash[top]=Hash[top-1]*base+b[i];
            Stack[top]=b[i];
            if(top>=lena){
                ULL t=getHashRange(top-lena+1,top);
                if(t==Hasha){
                    top=max(1,top-lena+1);
                }else
                    top++;
            }
            else
                top++;
        }
        Stack[top]='\0';
        printf("%s\n",Stack+1);
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值