SCU 4438

Censor

题目大意是有一个长的字符串P,然后有一些敏感词w  一个子串,一个母串,要求删除母串中的子串,删完剩余部分合并继续删,直到母串中不存在子串为止,输出此时的母串。


解析:扫一遍文本串,在扫描的时候,跟模式串匹配,将文本串字符和匹配字符个数压入栈,当匹配字符个数等于模式串长度时,将栈顶与模式串匹配的所有字符弹出,重新从栈顶元素的匹配个数开始计算下一次匹配(因为前面字符已经匹配了)。文本串扫完时,栈内所剩即为结果


#include <bits/stdc++.h>
//#include <ext/pb_ds/tree_policy.hpp>
//#include <ext/pb_ds/assoc_container.hpp>
//using namespace __gnu_pbds;
using namespace std;

#define pi acos(-1)
#define endl '\n'
#define me(x) memset(x,0,sizeof(x));
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
#define close() ios::sync_with_stdio(0);
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f3f3fLL;
const int dx[]={-1,0,1,0,-1,-1,1,1};
const int dy[]={0,1,0,-1,1,-1,1,-1};
const int maxn=1e4+5;
const int maxx=5e6+6;
const double EPS=1e-7;
const int MOD=1000000007;
#define mod(x) ((x)%MOD);
template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}
template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}
template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}
template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}
//typedef tree<pt,null_type,less< pt >,rb_tree_tag,tree_order_statistics_node_update> rbtree;
/*lch[root] = build(L1,p-1,L2+1,L2+cnt);
    rch[root] = build(p+1,R1,L2+cnt+1,R2);中前*/
/*lch[root] = build(L1,p-1,L2,L2+cnt-1);
    rch[root] = build(p+1,R1,L2+cnt,R2-1);中后*/
long long gcd(long long a , long long b){if(b==0) return a;a%=b;return gcd(b,a);}

int Next[maxx];
char y[maxx];
char x[maxx];
char out[maxx];
int n,m;
struct node
{
    char c;
    int k;
};
stack<node> ans;
void kmp_pre(char x[],int m)
{
    int i=0,j=Next[0]=-1;
    while(i<m)
    {
        while(j!=-1&&x[j]!=x[i]) j=Next[j];
        i++,j++;
        Next[i]=j;
    }
}
void kmp_count(char x[],char y[])
{  //x是模式串,m是模式串长度,y是主串,n是主串长度
    int i=0,j=0;
    while(i<m)
    {
        while(j!=-1&&x[j]!=y[i]) j=Next[j];
        i++,j++;
        ans.push(node{y[i-1], j});
        if(j>=n)
        {
            int len = n;
            while(len --) ans.pop();
            if(ans.empty()) j = 0;
            else j = ans.top().k;
        }
    }
    int cnt = 0;
    while(!ans.empty())
    {
        out[cnt ++] = ans.top().c;
        ans.pop();
    }
    for(int i=cnt-1; i>=0; i--) putchar(out[i]);
    printf("\n");
}
int main()
{
    while(scanf("%s%s",x,y)!=EOF)
    {
        n=strlen(x);
        m=strlen(y);
        kmp_pre(x,n);
        kmp_count(x,y);
    }

}
/*
abc
aaabcbc
b
bbb
abc
ab
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值