日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

字符串匹配算法(KMP)

發布時間:2024/7/5 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字符串匹配算法(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 匹配
class Solution { public:int strStr(string s, string p) {return kmp(s, p);}int kmp(string& s, string& p){int n1 = s.size(), n2 = p.size();vector<int> next(n2+1);calnext(p, next);int i = 0, j = 0;while(i < n1 && j < n2){if(j == -1 || s[i] == p[j]){i++,j++;}elsej = next[j];}if(j == n2)return i-j;return -1;}void calnext(string& p, vector<int>& next){int i = 0, j = -1;next[0] = -1;while(i < p.size()){if(j == -1 || p[i] == p[j]){i++,j++;next[i] = j;}elsej = next[j];}} };

0 ms 6.9 MB C++

總結

以上是生活随笔為你收集整理的字符串匹配算法(KMP)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。