KMP模板以及入門題型總結

2021-09-24 22:49:53 字數 3180 閱讀 7089

#include#include#define maxn 100010

using namespace std;

int next[maxn];

char s[maxn];

char p[maxn];

void prekmp(char x,int m,int next )

}return ans;

}//計數 不可重複

int kmpcount(char pp,int m,char ss,int n)

}return ans;

}//返回位置

int kmp(char pp,int m,char ss,int n)

}return -1;

}

題意就是給你兩個序列,讓你求b序列在a序列第一次出現(完全相同)的下標 

這道題是一道板子題,直接用返回位置的那個板子貼上就過了,不過還是要注意細節問題,輸入輸出盡量用printf、scanf,不然會tle,開陣列卡著邊界開,不然會mle,另外注意輸入輸出格式 ,不然會pe。**在下面?

#include#include#includeconst int maxn = 1e6+5;

using namespace std;

int next[maxn];

int pat[maxn];

int str[maxn];

void prekmp(int x,int m,int next)

}return -1;

}int main()

}return ans;

}int main()

}return ans;

}int main()

return 0;

}

題意為新增最少的字元使原字串變成週期至少為2的迴圈字串

這道題利用了next陣列的特性,結論是長度為m的pattern串的迴圈結長度為m-next[m]

**如下:

#include#include#includeusing namespace std;

const int maxn = 100005;

int next[maxn];

char pat[maxn];

void prekmp(char x,int m,int next)

}return 0;

}

本題題意為求m個字串長度至少為3的最長公共子串 

由於m只有10而且len小於60,我們可以選擇列舉某乙個串的子串並用str.find()或者kmp驗證是否所有該子串在所有字串**現過,也可以用經典的二分長度將height陣列分塊的字尾陣列做法 

poj3080(find解法

//由於只查詢是否出現過,演算法複雜度差距不大,所以這裡給出簡單一些的寫法

#include#include#include#includeusing namespace std;

const int maxn = 65;

char str[maxn];

string ansstr;

string str2[maxn];

int main()

void getsa(int *r,int *sa,int n,int m)

}void getheight(int *r,int n)

i++;

}if(!vis[belong[sa[i-1]]])

if(cnt>=t)

}return false;

}int main()

if(r<3) printf("no significant commonalities \n");

else

if(ans==0)

for(int i=0;i

本題題意為求字串的每個字首在整個字串中的出現次數。 

我們想象性質二,如果next[j]對答案有乙個貢獻,那麼這個貢獻在j中一定會再貢獻一次,而且j為結尾的字串對於總串產生的貢獻只有長度為j的子串,於是我們可以得到轉移方程ans[j]=ans[next[j]]+1ans[j]=ans[next[j]]+1,最後對所有字首的貢獻取和即為答案。 

hdu3336**

#include#include#include#includeusing namespace std ;

const int maxn = 1e6+5;

int next[maxn];

char str[maxn];

char mo[maxn];

int dp[maxn];

int n1,n2;

void getnext()

for(int i=0;i多個字串的最長公共子串,只不過子串可以逆置出現,只要把第八題的做法反過來再找一次就好,直接上**

#include#include#include#includeusing namespace std;

const int maxn = 105;

char str[maxn];

string ansstr;

string str2[maxn];

int main()

}return i0)

else if(i+k+1 > j) i = i+k+1;

else i = j+1;

k = 0;}}

return i < j ? i : j;

}int ans[maxn];

int main()

else

}return 0;

}

本題為給你n個01串,可以對每個串旋轉任意次,求最少出現多少個不同的字串,我們可以知道,如果兩個字串是可以旋轉之後相同的,那麼他們的最小表示法一定是相同的,所以我們可以求出所有字串的最小表示法,然後用乙個set去重就好了。 

hdu2609**

#include#include#include#include#includeusing namespace std;

int getmin(char *s)

}return is;

int main()

return 0;

}

未完待續。。。

拓展KMP以及模板

廢話不多說,上模板 includeconst int maxn 1e6 10 int next maxn extend maxn mol,strl next陣列 extend陣列 模式串長度 母串長度 char mo maxn s maxn 模式串 母串 void getnext 求解模式串 mo ...

KMP模板 和入門題

hdu1711 題意就是給你兩個序列,讓你求b序列在a序列第一次出現 完全相同 的下標 本題就是kmp的模板題,將i指標指向a串,將j指標指向b串,如果匹配就繼續下一位的匹配,如果不匹配,將j跳轉到next j 繼續向前匹配。include define inf 0x3fffffff define ...

拓展KMP演算法 入門 模板

擴充套件kmp演算法,圖很形象,寫的也很清晰,下面的模板就是出自該部落格文章。拓展kmp是求母串s長度為n和子串t長度為m,求s的每乙個字尾子串與t的字首子串匹配的最長長度。求解模式串t的next陣列,這個函式和下面的函式幾乎相同 void getnext string t,int m,int ne...