问题PRO_8_8
智英的梦想是独裁者,为了独裁,阻止国民抵抗权利的事情则非常重要,因此审查刊物是必须要做的事情。
你作为智英的朋友,决定帮助智英审查字符串。
准确的审查方法如下
*检查字符串S中是否存在样本T。
*若存在样本T,则删除此样本首次出现的位置。
*一直重复操作直到没有样本为止。
输入
在第一行给出字符串S,S的最大长度是1,000,000
在下一行给出要检查的样本T,T的长度要小于S
S和T都只能由小写的罗马字符构成。
输出
按照在问题中说明的审查方法输出从字符串中删除样本T的字符串。
案例输入
Whatthemomooofun
moo
案例输出
whatthefun
#include<cstdio>
#include<cstring>
const int max = 1000001;
char s[max], t[max], o[max];
int nextj[max], lastmatch[max];
int slen, tlen,olen;
// ex. abcab->nextj[00012]
// abcacaaaaaaaaaaaa abcacaaaaaaaaaaaa
// abcab--> abcab
void getNext(){
nextj[0] = 0;
for (int i = 1; i < tlen; i++){
int matched = nextj[i - 1];
while (t[i] != t[matched]){
if (matched == 0) break;
matched = nextj[matched - 1];
}
// update next[]
if (t[i] == t[matched]) nextj[i] = matched + 1;
else nextj[i] = 0;
}
}
void match(){
for (int i = 0; i < slen; i++){
int matched = lastmatch[olen];
while (s[i] != t[matched]){
if (matched == 0) break;
matched = nextj[matched - 1];
}
// copy char to output char array.
o[olen] = s[i];
olen++;
if (s[i] == t[matched]){
lastmatch[olen] = matched + 1;
if ((matched + 1) == tlen){
// t is full matched
olen -= tlen; // back tlen chars(over it after)
}
}
else{
// clear matched length,for union match after some chars was deleted
lastmatch[olen] = 0;
}
}
// append end flag for output chars;
// like whatthefun\0ooo
o[olen++] = 0;
return;
}
int main(){
scanf("%s%s", s, t);
slen = strlen(s);
tlen = strlen(t);
// calculate the next function by KMP
getNext();
// find and delete t string in s string;
match();
// print output chars in o[];
printf("%s\n", o);
return 0;
}
import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
*
whatthemomooofun moo
*
* @author Administrator
*
*/
public class source {
// 目标字符串
static String target;
// 需要查找的字符串
static String partern;
// kmp结果
static int[] next;
// 输出数组
static char[] out;
// 输出数组最后索引
static int idx = 0;
/**
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
target = br.readLine();
partern = br.readLine();
// KMP处理
getNext();
kmp();
System.out.println(new String(out , 0 ,idx));
br.close();
}
private static void kmp() {
int targetLength = target.length();
int parternEndIndex = partern.length();
out = new char[target.length()];
int[] match = new int[targetLength];
for(int i=0;i<targetLength ;i++)
{
int pindex = match[idx];
while(target.charAt(i)!=partern.charAt(pindex)){
if(pindex ==0) break;
pindex = next[pindex-1];
}
out[idx] = target.charAt(i);
idx++;
// matched
if(target.charAt(i)== partern.charAt(pindex)){
match[idx] = pindex +1;
// matched all
if ((pindex +1) == parternEndIndex) idx -=parternEndIndex;
}else match[idx]=0;
}
out[idx] =0;
}
/**
* 如果当前字符没有匹配成功,则匹配字符串需要左移的个数存入数组next中
*
* @return
*/
private static int[] getNext() {
int length = partern.length();
next = new int[length];
next[0] = 0;
for(int i=1;i<length;i++){
int matched=next[i-1];
while(partern.charAt(i)!=partern.charAt(matched)){
if(matched==0) break;
matched = next[matched-1];
}
if(partern.charAt(i) == partern.charAt(matched)) next[i] = matched+1;
else next[i]=0;
}
return next;
}
}