- 题意:两个字符串w, p。 执行以下操作,1.如果p中含有w,将第一个遇到的w删除,剩下的连接起来。2.如果p中还有w重复1,否则输出处理后的字符串。
- 思路:可以用一个栈来处理这个问题,其中匹配可以采用kmp算法,也可以用hash。
- 代码:
//kmp
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5000000 + 5;
char w[maxn], p[maxn];
char ans[maxn];
int next[maxn];
void getnext(char *str, int next[])
{
int len = strlen(str);
next[0] = -1;
int j = 0, k = -1;
while(j < len) {
if(k == -1 || str[j] == str[k]) {
j++; k++;
if(str[j] == str[k]) {
next[j] = next[k];
} else {
next[j] = k;
}
} else {
k = next[k];
}
}
}
int main()
{
while(scanf("%s%s", w, p) == 2) {
//memset(ans, 0, sizeof(ans));
getnext(w, next);
stack<char> sta;
stack<int> mt;
int plen = strlen(p), wlen = strlen(w);
int j = 0, k = 0;
while(j < plen) {
if(k == -1 || p[j] == w[k]) {
j++; k++;
sta.push(p[j-1]);
mt.push(k);
if(k == wlen) {
for(int i = 0; i < wlen; i++) {
sta.pop();
mt.pop();
}
if(mt.empty()) {
k = 0;
}
else k = mt.top();
}
} else {
k = next[k];
}
}
int i = sta.size() - 1;
ans[i+1] = '\0';
while(!sta.empty()) {
ans[i--] = sta.top();
sta.pop();
}
printf("%s\n", ans);
}
return 0;
}
//hash
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5000000 + 5;
const int seed = 1331;
typedef unsigned long long ull;
char w[maxn], p[maxn];
char ans[maxn];
ull _hash[maxn];
int main()
{
while(~scanf("%s%s", w, p)) {
ull mhash = 0;
unsigned int wlen = strlen(w), plen = strlen(p);
ull k = 1;
for(int i = 0; i < wlen; i++) {
mhash = mhash*seed + w[i];
k *= seed;
}
stack<char> sta;
int i = 0, len = 1;
_hash[0] = 0;
for(; i < plen; i++, len++) {
_hash[len] = _hash[len - 1] * seed + p[i];
sta.push(p[i]);
if(len >= wlen) {
if(_hash[len] - _hash[len - wlen]*k == mhash) {
for(int j = 0; j < wlen; j++) {
sta.pop();
}
len = len - wlen ;
}
}
}
int j = sta.size();
ans[j--] = '\0';
while(!sta.empty()) {
ans[j--] = sta.top();
sta.pop();
}
printf("%s\n", ans);
}
return 0;
}