KMP的一點理解

2021-08-28 03:36:19 字數 1421 閱讀 6532

假設現在我們面臨這樣乙個問題:有乙個文字串s,和乙個模式串p,現在要查詢p在s中的位置,怎麼查詢呢?

我們可以利用雙指標的方式進行匹配但這時乙個非常消耗時間的問題出來了,一旦失配應該怎麼匹配,這時今天的主角就要登場啦,我們可以設乙個陣列用於記錄在失配點之前有多少個點是可以直接繼續匹配的,比如說對「123121」進行匹配「12312312」當匹配到第二個3的時候適配這時的失配點的之前123是可以用的,不妨我們可以這樣想能夠繼續用的部分即是其開始匹配的地方在後方重複的地方的即可以看成其字首和字尾,那麼失配時,模式串向右移動的位數為:已匹配字元數 - 失配字元的上一位字元所對應的最大字首字尾相等長度值,於是我們可以定義乙個next陣列。

next 陣列各值的含義:代表當前字元之前的字串中,有多大長度的相同字首字尾。例如如果next [j] = k,代表j 之前的字串中有最大長度為k 的相同字首字尾。

故kmp的主要流程是:

假設現在文字串s匹配到 i 位置,模式串p匹配到 j 位置

如果j = -1,或者當前字元匹配成功(即s[i] == p[j]),都令i++,j++,繼續匹配下乙個字元;

如果j != -1,且當前字元匹配失敗(即s[i] != p[j]),則令 i 不變,j = next[j]。此舉意味著失配時,模式串p相對於文字串s向右移動了j - next [j] 位。

換言之,當匹配失敗時,模式串向右移動的位數為:失配字元所在位置 - 失配字元對應的next 值(next 陣列的求解會在下文的3.3.3節中詳細闡述),即移動的實際位數為:j - next[j],且此值大於等於1。

kmp模板:

#include#include#include#include#include#define n 100005

using namespace std;

int n,m;

int a[n];

int b[n];

int i,j;

///找k的位置使b是a的子串

int next[n];

void makenext(int *str, int *next, int len)

if (str[k + 1] == str[q])//如果相同,k++

next[q] = k;//這個是把算的k的值(就是相同的最大字首和最大字尾長)賦給next[q]

}}int kmp(int *str, int slen, int *ptr, int plen)

printf("\n");

int k = -1;

for (int i = 0; i < slen; i++)

}return -1;

}int main()

for(int j=1;j<=m;j++)

int ans=kmp(a,n,b,m);

printf("%d\n",ans);

}}

有關KMP的一點點理解

最近返回頭研究kmp演算法 再讀一邊教材,還是覺得書上寫的十分抽象,對於小菜們來說,很難理解。自己翻書查資料,畫圖,測試,終於有了一點點收穫,自己寫了乙個kmp關於特徵向量的演算法,雖然不如書上的簡潔,但是容易理解。希望可以對剛學kmp的同學有所幫助。kmp的原理在這兒就不多說了,就是運用特徵向量減...

KMP的一點心得

int next next陣列儲存的是當模式串匹配不上的時候將要跳轉的下標 void getnext char b int kmp char a,char b 尋找主串中有多少模式串 return k int kmp char a,char b 判斷主串中是否有模式串 return 0 字串a代表的...

UIWebView 的一點理解

uiwebview可以用來方便得顯示url request uiwebview 是從uiview繼承而來的。所以本身並沒有實現scroll。當開啟乙個urlrequest之後,uiwebview 自動建立乙個uiscrollview add 到uiwebview的layer 當開啟當前頁面中的lin...