En la actualidad, para problemas básicos de cadenas, las soluciones existentes KMP, siguiente problema de matriz, hash, Manacher, coincidencia de fuerza bruta, árbol de reglas y diccionario, para matrices de sufijos, autómatas ac y autómatas de sufijo, la subcadena
kmp
está en la cadena principal. número de ocurrencias para resolver el problema de la correspondencia de cadenas
char a[maxn],b[maxn];
ll lena,lenb;
int next1[maxn];
void getnext(){
next1[0]=-1;
int i=0,j=-1;
while(i<lena){
//子串
if(j==-1||a[i]==a[j]){
//子串
i++;j++;
if(a[i]==a[j]) next1[i]=next1[j];
else next1[i]=j;
}
else{
j=next1[j];
}
}
}
int KMP(){
int i=0,j=0,ans=0;
while(i<lena&&j<lenb){
//子串 母串
if(i==-1||a[i]==b[j]){
i++;j++;
}
else i=next1[i];
if(i==lena){
ans++;//出现次数....
i=next1[i];
}
}
return ans;
}
Buscar por separado la siguiente matriz: resolver el problema de las ocurrencias repetidas del tipo de anillo y algunos juicios sobre la definición
int next1[maxn];
void getnext()
{
next1[0]=-1;
int i=0,j=-1;
while(i<lena)
{
if(j==-1||a[i]==a[j])
{
i++;j++;
if(a[i]==a[j])next1[i]=next1[j];
else next1[i]=j;
}
else
{
j=next1[j];
}
}
}
Hash: use un número para almacenar una cadena y juzgue el número con otras cadenas. Es principalmente un método para resolver el problema de la coincidencia de cadenas
ll hash1[maxn];
int lena,lenb;
for(int i=0;i<lena;i++){
sum=sum*base+(int)a[i];
}//子串的哈希值
hash1[0]=0;
for(int i=1;i<=lenb;i++){
hash1[i]=hash1[i-1]*base+b[i-1];
}//每个位置上从前向后的哈希值
Tablero de carro tirado por caballos: resuelve el problema de la longitud del palíndromo en la cuerda
string Manacher(string s1){
string s="$#";//占空位0插入符号1
for(int i=0;i<s1.size();i++)
s+=s1[i],s+='#';
vector<int>p(s.size(),0);//p储存回文串长度
int id=0,mx=0,maxpoint=0,maxlen=0;//mx对应最右边 id为对应中点 maxpoint最长回文对应中点 maxlen最长长度
for(int i=1;i<s.size();i++){
p[i]=mx>i+p[i]?min(mx-i,p[2*id-i]):1;
while(s[i+p[i]]==s[i-p[i]]) ++p[i];
if(i+p[i]>mx) id=i,mx=i+p[i];//更新右端和中间,节间更新左边端点
if(p[i]>maxlen) maxlen=p[i],maxpoint=i;//更新最大长度和对应中心点
}
return s1.substr((maxpoint-maxlen)/2,maxlen-1);//s1中最长回文串
}
Coincidencia violenta: es decir, para juzgar la posición de cada carácter en la cadena principal, si coincide, juzgue si el siguiente carácter coincide, de lo contrario, salte a la siguiente posición
Recientemente aprendí un poco sobre el contenido de los autómatas ac. Lo escribiré en detalle cuando ponga una pregunta complementaria en la parte posterior de la pizarra. Recuerde que esta es la pregunta escrita por el código ascall.
int trie[maxn][4], fail[maxn], tail[maxn];
int n, m, pos;
char s[15];
map<char, int>idx;
void insert(){
int ls=strlen(s),root=0;
for(int i=0;i<ls;i++){
int x=idx[s[i]];
if(trie[root][x]==0)
trie[root][x]=++pos;
root=trie[root][x];
}
tail[root]=1;
}
void getfail(){
queue<int>qu;
for(int i=0;i<4;i++){
if(trie[0][i]){
fail[trie[0][i]]=0;
qu.push(trie[0][i]);
}
}
while(!qu.empty()){
int now=qu.front();
qu.pop();
for(int i=0;i<4;i++){
if(trie[now][i]){
fail[trie[now][i]]=trie[fail[now]][i];
qu.push(trie[now][i]);
}
else trie[now][i]=trie[fail[now]][i];
tail[trie[now][i]]|=tail[trie[fail[now]][i]];
}
}
}
La cuerda del palíndromo más larga
En términos generales, el palíndromo más largo utiliza un carro tirado por caballos y también puede ser transferido por dp bidimensional. Para una cadena, usamos dp [i] [j] para representar la subsecuencia de palíndromo más larga desde el carácter i-ésimo hasta el carácter j de la cadena.
Si s [i] == s [j] entonces se puede transferir A ambos lados de la subsecuencia palíndromo, todos los dp [i] [j] = d [i + 1] [j-1] +2
si s [i]! = S [j] no se pueden transferir a ambos lados del subsecuencia palíndromo al mismo tiempo, Entonces dp [i] [j] = max (d [i + 1] [j], dp [i] [j-1])
Para que la diferencia entre dos cuerdas forme el palíndromo más largo, hay
#include<bits/stdc++.h>
using namespace std;
char a[55],b[55];
int f[55][55][55][55];
int main(){
int t;
cin>>t;
while(t--){
scanf("%s",a+1);
scanf("%s",b+1);
int m,n;
n=strlen(a+1);
m=strlen(b+1);
int ans=0;
for(int len1=0;len1<=n;len1++)
for(int len2=0;len2<=m;len2++)
for(int i=1;i+len1-1<=n;i++)
for(int j=1;j+len2-1<=m;j++){
int r=i+len1-1;
int l=j+len2-1;
if(len1+len2<=1) f[i][r][j][l]=1;
else{
f[i][r][j][l]=0;
if(len1>1) f[i][r][j][l]|=((f[i+1][r-1][j][l])&&(a[i]==a[r]));
if(len1&&len2) f[i][r][j][l]|=(f[i+1][r][j][l-1]&&(a[i]==b[l]));
if(len1&&len2) f[i][r][j][l]|=(f[i][r-1][j+1][l]&&(a[r]==b[j]));
if(len2>1) f[i][r][j][l]|=(f[i][r][j+1][l-1]&&(b[j]==b[l]));
}
if(f[i][r][j][l]){
ans=max(ans,len1+len2);
}
}
cout<<ans<<endl;
}
system("pause");
return 0;
}