P4824 [USACO15FEB] Censoring S

请读者在阅读前充分理解KMP与其失配函数的意义。

题目描述

原题来自:USACO 2015 Feb. Silver

给出两个字符串 S 和 T,每次从前往后找到 S 的一个子串 A=T 并将其删除,空缺位依次向前补齐,重复上述操作多次,直到 S 串中不含 T 串。输出最终的 S 串。

输入格式
第一行包含一个字符串 S,第二行包含一个字符串 T。

输出格式
输出处理后的 S 串。

样例

输入
whatthemomooofun
moo
输出
whatthefun
数据范围与提示
对于全部数据, 1 ≤ ∣ T ∣ ≤ ∣ S ∣ ≤ 1 0 6 1\le |T|\le |S|\le 10^6 1TS106,保证字符串中只出现小写字母。

代码

#include<bits/stdc++.h>
const int M=1e7; 
char a[M],b[M];int n,m,s[M],st[M],top=0;
using namespace std;
int f[M];
void getfail(char *a,int *f){
	int j=0;
	f[0]=f[1]=0;
	for (int i=1;i<m;i++){
		while(j and a[i+1]!=a[j+1]) j=f[j];
		if (a[i+1]==a[j+1]) j++;
		f[i+1]=j; 
	}
}
int main(){
	scanf("%s",a+1);scanf("%s",b+1);
	n=strlen(a+1);m=strlen(b+1);
	getfail(b,f);
	int j=0;
	for (int i=0;i<n;i++){
		while (j and a[i+1]!=b[j+1]) j=f[j];
		if (a[i+1]==b[j+1]) j++;
		s[i]=j;
		st[++top]=i;
		if (j==m){
			top-=m;
			j=s[st[top]];
		}
	}
	for (int i=1;i<=top;i++)
		cout<<a[st[i]+1];
	return 0;
}

分析

getfail是求失配数字的函数,与其他的KMP并无区别,在这里不过多赘述。

for (int i=0;i<n;i++){
		while (j and a[i+1]!=b[j+1]) j=f[j];
		if (a[i+1]==b[j+1]) j++;
		s[i]=j;
		st[++top]=i;
		if (j==m){
			top-=m;
			j=s[st[top]];
		}
	}

匹配有点不同,这里多了两个数组:
1.s是一个记录数组,用于记录主串在匹配i处时,匹配串匹配了j个元素
2.st是手打栈,而top是栈顶下标,存放主串的下标
在匹配时,若成功匹配,回到之前的j
比如样例:
j值的变化:3->2,3->0

for (int i=1;i<=top;i++)
		cout<<a[st[i]+1];

由于下标从1开始,所以+1;

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值