字符串匹配算法(KMP)
生活随笔
收集整理的這篇文章主要介紹了
字符串匹配算法(KMP)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 1. KMP由來
- 2. KMP算法基本原理
- 3. 代碼
- 4. Leetcode 28. 實現 strStr()
1. KMP由來
- 上一節說的BM算法是最高效、最常用的字符串匹配算法。
- 最知名的卻是KMP,它3位作者(D.E.Knuth,J.H.Morris,V.R.Pratt),算法的全稱是Knuth Morris Pratt 算法,簡稱KMP算法。
2. KMP算法基本原理
類似于BM里的概念:壞字符(不能匹配的),好前綴(已經匹配的那段)
-
KMP算法目的:當遇到壞字符后,對于已經對比過的好前綴,將模式串多滑動幾位
借一張圖理解一下:
上面可以看出,可以事先預處理好模式串,與主串比較時,直接用next數組 -
構建next數組(失效函數)
next 數組含義:當前字符之前的字符串(不含當前)中,最大長度的相同前綴后綴子串。如果next [j] = k,代表 j 之前的字符串中有最大長度為 k 的相同前綴后綴子串。 -
失效函數計算方法
方法1:暴力求解子串長度,效率低
方法2:
case1
case2
如果 b[k] != b[j] , 則我要在前面部分里尋找能和包含 b[j] 的后綴匹配的最長前綴子串;
b[k] 前面的最長匹配前綴長度就是 next[k],那么其后面一個字符就是 b[ next[k] ],如果它等于b[j],那么next[j+1] = next[k] + 1
參考文獻
3. 代碼
王爭的代碼不好理解,找了書和別的人的代碼參考
/*** @description: KMP字符串匹配算法* @author: michael ming* @date: 2019/6/22 17:15* @modified by: */ #include <string> #include <iostream> using namespace std; void calNexts(char *b, int m, int *next) {next[0] = -1;int j = 0, k = -1;while(j < m){if(k == -1 || b[j] == b[k]){j++;k++;next[j] = k;}elsek = next[k];} // for(j = 0; j < m; ++j)//調試代碼 // cout << "next[" << j << "] " << next[j] << endl; } int str_kmp(char *a, int n, char *b, int m) {int *next = new int [m];calNexts(b, m, next);int i = 0, j = 0;while(i < n && j < m){if(j == -1 || a[i] == b[j]){i++;j++;}else{j = next[j];}}if(j == m){delete [] next;return i-j;}delete [] next;return -1; } int main() {string a = "abcacabcbcbaccba", b = "cbaccba";cout << a << "中第一次出現" << b << "的位置(從0開始)是:" << str_kmp(&a[0],a.size(),&b[0],b.size());return 0; }時間復雜度O(n+m),空間復雜度O(m)
4. Leetcode 28. 實現 strStr()
- 使用 kmp 匹配
0 ms 6.9 MB C++
總結
以上是生活随笔為你收集整理的字符串匹配算法(KMP)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图Graph--寻找二度好友(BFS应用
- 下一篇: LeetCode 46. 全排列(回溯)