bzoj3942
有一个S串和一个T串,长度均小于1,000,000,设当前串为U串,然后从前往后枚举S串一个字符一个字符往U串里添加,若U串后缀为T,则去掉这个后缀继续流程。
将s中的每一个字符压入栈
暴力将s中的字符和t中的一个一个匹配,若能够匹配
若不能匹配,我们利用next数组转移匹配的位置
同时我们利用另一个栈来存储匹配到的位置,这意味着我们的两个栈时同时进栈同时出栈的
当我们匹配到的长度为t的长度时,我们将栈中的"t"出栈
如此进行
最后输出栈中剩余字符
口胡有点说不清,建议看代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn = 1000086; 4 char s[maxn], t[maxn]; 5 int Next[maxn]; 6 int s2[maxn], top = 0; 7 char s1[maxn]; 8 int lens, lent; 9 10 inline void KMP_T() { 11 Next[1] = 0; 12 for(int i = 2, j = 0; i <= lent; ++i) { 13 while(j > 0 && t[i] != t[j + 1]) j = Next[j]; 14 if(t[i] == t[j + 1]) j++; 15 Next[i] = j; 16 } 17 /*for(int i = 1; i <= lent; ++i) 18 cout << Next[i] << ' '; 19 cout << '\n';*/ 20 } 21 22 int main() { 23 cin >> s + 1 >> t + 1; 24 lens = strlen(s + 1); 25 lent = strlen(t + 1); 26 KMP_T(); 27 for(int i = 1; i <= lens; ++i) { 28 int j = s2[top]; 29 s1[++top] = s[i]; 30 while(j != 0 && s1[top] != t[j + 1]) j = Next[j]; 31 if(s1[top] == t[j + 1]) j++; 32 s2[top] = j; 33 if(s2[top] == lent) top -= lent; 34 } 35 for(int i = 1; i <= top; ++i) 36 cout << s1[i]; 37 cout << '\n'; 38 return 0; 39 }