字符串算法总结
1、KMP
求字符串匹配
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char A[1000010], B[1010];
int next[1010];
int main()
{
scanf("%s %s", A, B);
int lena = strlen(A), lenb = strlen(B);
for(int i=1, j=0; i < lenb; i++){
while(j>0 && B[i]!=B[j]) j = next[j-1];
if(B[i] == B[j]) next[i] = ++j;
}
for(int i=0, j=0; i < lena; i++){
while(j>0 && A[i]!=B[j]) j = next[j-1];
if(A[i] == B[j]) ++j;
if(j == lenb){
printf("%d\n", i-lenb+2);
}
}
for(int i = 0; i < lenb; i++) printf("%d ", next[i]);
return 0;
}
2、Manacher
求最长回文子串
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char S[100010], H[100010];
int G[100010], mx, ans, len, id;
int main()
{
scanf("%s", S);
len = strlen(S);
H[0] = '$'; H[1] = '#';
for(int i = 0; i < len; i++){
H[i*2+2] = S[i];
H[i*2+3] = '#';
}
len = len * 2 + 2;
H[len] = '\0';
for(int i = 1; i < len; i++){
if(i < mx) G[i] = min(G[id*2-i], G[id]+id-i);
else G[i] = 1;
while(H[i-G[i]] == H[i+G[i]]) G[i]++;
if(mx < G[i]+i){
mx = G[i] + i;
id = i;
}
ans = max(ans, G[i]-1);
}
printf("%d", ans);
return 0;
}
3、最小表示法
判断字符串是否循环同构
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int len;
char S[5000010];
int Work(){
int i = 0, j = 1;
while(i<len && j<len){
int k = 0;
while(S[(i+k)%len]==S[(j+k)%len] && k<len) k++;
if(k==len) return min(i, j);
if(S[(i+k)%len] > S[(j+k)%len]) i = i+k+1;
else j = j+k+1;
if(i == j) j++;
}
return min(i, j);
}
int main()
{
scanf("%d", &len);
for(int i = 0; i < len; i++) cin >> S[i];
printf("%d", Work());
return 0;
}
…
未完待续