~欢迎你!第 AmazingCounters.com 位造访者

ACM: SCU 4438 Censor - KMP

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

Description

Censor

frog is now a editor to censor so-called sensitive words (敏感词).

She has a long text pp. Her job is relatively simple -- just to find the first occurence of sensitive word ww 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 11 string ww. The second line contains 11 string pp.

(1length of w,p51061≤length of w,p≤5⋅106, w,pw,p consists of only lowercase letter)

Output

For each test, write 11 string which denotes the censored text.

Sample Input

    abc
    aaabcbc
    b
    bbb
    abc
    ab

Sample Output

    a
    
    ab

/*/
题意:
给出两个字符串T和S,把所有在S中出现的T删掉,并且合并S,如果合并后还有T继续删掉。

KMP算法,练习

关键在于next表的建立,还有怎么利用next去查询字符串是否相同。

这里推荐一个大佬的博客,我也是从上面学习到的:
next->door( http://blog.csdn.net/sjf0115/article/details/8579484 )

然后KMP主要有两种用法,一种是用数组+模拟指针去覆盖掉匹配了的字符串,一种是用栈去弹掉匹配成功的串串,理论基本相同。

AC代码:
/*/

#include"algorithm"
#include"iostream"
#include"cstring"
#include"cstdlib"
#include"cstdio"
#include"string"
#include"vector"
#include"stack"
#include"queue"
#include"cmath"
#include"map"
using namespace std;
typedef long long LL ;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define FK(x) cout<<"["<<x<<"]\n"
#define memset(x,y) memset(x,y,sizeof(x))
#define memcpy(x,y) memcpy(x,y,sizeof(x))
#define bigfor(T)  for(int qq=1;qq<= T ;qq++)

const int MX=5555555;
/***************************************************/
char s[MX],t[MX],ans[MX];
int  next[MX],pos[MX],len1,len2;

void init() {
	memset(ans,0);
	memset(pos,0);
	memset(next,0);
}

struct Node {
	char ch;
	int j;
	Node() {};
	Node(char c,int n):ch(c),j(n) {};
};

void GetNext() {
	int i=0,j=-1;
	next[0]=-1;
	while(i<len2) {
		if(j==-1||t[i]==t[j]) {
			i++;
			j++;
			if(t[i]==t[j]) {
				next[i]=next[j];
			} else next[i]=j;
		} else j=next[j];
	}
}

void KMPStack() {
	int i = 0, j = 0;
	stack<Node> st;
	while(i < len1) {
		if(j == -1 || s[i] == t[j]) {//如果前面找不到相匹配的字符或者两个字符相同,加入栈。
			j ++;
			st.push(Node(s[i], j));
			i ++;
		} else j = next[j];
		if(j == len2) {  //匹配成功把栈内的匹配到的T串弹出。
			int len = len2;
			while(len --) st.pop();
			if(st.empty()) j = 0;//如果栈已经空了j返回到0;
			else j = st.top().j;	 //如果不是空的,j变为最后一个字符的next值。
		}
	}
	int cnt = 0;
	while(!st.empty()) {
		ans[cnt ++] = st.top().ch;
		st.pop();
	}
	for(int i=cnt-1; i>=0; i--) {
		putchar(ans[i]);
	}
	puts("");
}

/************************************************/
void KMP() {
	int i=0,j=0;
	int cnt=0;
	while(i<len1) {
		ans[cnt]=s[i++];  //字符串一个个的往暗示里面读入
		while(!(j==-1||ans[cnt]==t[j])) {
			j=next[j];
		}
		j++;
		cnt++;     //模拟指针
		pos[cnt]=j;
		if(j==len2) {  //如果找到匹配字符串长度的,指针指回该被匹配到的字符串最初位置
			cnt-=len2;
			j=pos[cnt];
		}
	}
//	puts(ans);
	for(int i=0; i<cnt; i++) {
		putchar(ans[i]);
	}
	puts("");
}
/************************************************/

int main() {
	while(~scanf("%s %s",t,s)) {
		init();
		len1=strlen(s);
		len2=strlen(t);
		GetNext();
//		KMP();	   //数组 
		KMPStack();//栈 
	}
	return 0;
}

  

 

 

 
posted @ 2016-08-18 16:07  ~HDMaxfun  阅读(765)  评论(0编辑  收藏  举报