String subject KMP, next array problem, hash, Manacher, brute force matching, ruler taking, ac automata, kuangbin question sheet

At present, for basic string problems, the existing solutions KMP, next array problem, hash, Manacher, brute force matching, ruler and dictionary tree, for suffix arrays, ac automata and suffix automata, the
kmp
substring is in the parent string. The number of occurrences to solve the problem of string matching

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;
}

Separately seeking the next array: solve the problem of recurring and recurring loops, and some judgments on the definition

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 a number to store a string, and judge the number with other strings. It is mainly a method to solve the problem of string matching

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];
}//每个位置上从前向后的哈希值

Horse-drawn cart board: Solve the problem of palindrome length in the string

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中最长回文串
}

Violent matching: that is, to judge each character position on the parent string, if it matches, judge whether the following character matches, otherwise jump to the next position

Recently I learned a little bit of the content of ac automata. I will write it in detail when I put it on the back of the board, remember that this is the question written by the ascall code.

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]];
        }
    }
}

The longest palindrome string
Generally speaking, the longest palindrome uses a horse-drawn cart, and it can also be transferred by two-dimensional dp. For a string, we use dp[i][j] to represent the longest palindrome subsequence from the i-th character to the j-character of the string.
If s[i]==s[j] then it can be transferred To both sides of the palindrome subsequence, all dp[i][j]=d[i+1][j-1]+2

if s[i]!=s[j] can not be transferred to both sides of the palindrome subsequence at the same time, So dp[i][j]=max(d[i+1][j],dp[i][j-1])


For the difference between two strings to form the longest palindrome, there is

#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;
}

Guess you like

Origin blog.csdn.net/qq_45891413/article/details/109123713