kmp演算法之前需要說一點串的問題:
串:
字串:ascii碼為基本資料形成的一堆線性結構。
串是乙個線性結構;它的儲存形式:
typedef struct string ;
樸素的串匹配演算法:
設文字串text = "ababcabcacbab",模式串為patten = "abcac" 其匹配過程如下圖所示。
黑色線條代表匹配位置,紅色斜槓代表失配位置
一般匹配字串時,我們從目標字串text(假設長度為n)的第乙個下標選取和patten長度(長度為m)一樣的子字串進行比較,如果一樣,就返回開始處的下標值,不一樣,選取text下乙個下標,同樣選取長度為n的字串進行比較,直到str的末尾(實際比較時,下標移動到n-m)。在普通的匹配中,假如從文字串的第i個字元來開始於模式串匹配。當匹配到模式串的第j位發現失配,即text[i+j] != patten[j]的時候,我們又從文字串的第i+1個位置來重新開始匹配。儘管我們已經知道了好多字元其實根本就匹配不上,我們還是進行了這個過程,這個時候回溯的過程會非常耗費我們的時間。這樣的時間複雜度是o(n*m)。
**如下:
int search(constkmp演算法:而kmp演算法的實質就是,當遇到text[i+j] != patten[j]的時候,但是我們知道模式串中的 0~j-1 位置上的字元已經於i ~ i+j-1位置上的字元是完全匹配的。就不再重新從text[i+1]開始匹配,而是根據next陣列的下標找到patten的下標,從那個下標開始匹配。從而時間複雜度為o(m+n)。char*str,const
char *substr) 判斷substrlen是否比較完成 }}
例如模式串patten = "abaabcac"。其next陣列如圖所示:
我們可以看到這次的匹配在藍色的c失配了,而c的下標為5,他的next陣列的下標為2。因此,下次的匹配不再是從text[1]開始,而是從text[2]開始,這樣就省去了不必要的比較。
**如下:
#include #include#include
#include
"kmpmec.h
"void getnext(const
char *str, int *next);
int kmpsearch(const
char *str, const
char *substr);
int kmpsearch(const
char *str, const
char *substr)
next = (int *) calloc(sizeof(int
), sublen);
if (sublen > 2
)
while (strlen - i + next[j] >=sublen)
if (substr[j] == 0
) else
if (j == 0
) else
}free(next);
return -1;}
void getnext(const
char *str, int *next)
else
if (j == 0
) else}}
}int main(void
) else
return0;
};
KMP演算法 next陣列
通過上文完全可以對kmp演算法的原理有個清晰的了解,那麼下一步就是程式設計實現了,其中最重要的就是如何根據待匹配的模版字串求出對應每一位的最大相同前字尾的長度。我先給出我的 1 void makenext const char p,int next 214 next q k 15 16 現在我著重講...
KMP演算法 NEXT陣列
kmp和next陣列基本上是一起用的,有了next陣列,才有kmp演算法,講道理來說這兩個都是基於最大前字尾和,也就是說需要用到kmp的時候必須先把next陣列先求出來,next陣列就是由所匹配的word的每個子串的前字尾和最大匹配得到的,說實話next陣列的演算法給優化得已經很無解了,以至於至今我...
kmp演算法next例題 KMP演算法next陣列求解
kmp演算法與bf演算法的比較 bf演算法的想法十分樸素,即先將子串t的第一位與主串s的第一位對齊開始匹配,當不能匹配時將子串整體往後移一位,然後重新匹配,以此類推直至排出結果 如當遇到下圖所示情況時,需將子串整體後移一位,將i,j分別回溯到主串第2位和子串第一位。kmp演算法 對bf進行思考後,我...