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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

KMP算法的学习经验

發布時間:2024/1/17 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 KMP算法的学习经验 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

KMP算法的學習經驗

(歡迎指正錯誤, 歡迎噴)

  • 什么是kmp(完)
  • kmp的額外知識(完)
  • 暴力匹配的缺點,和代碼實現(完)
  • next[]數組的預先知識,了解前后綴,相同前后綴。(完)
  • kmp的關鍵next[]數組, next的實現。(完)
  • next數組中k = next[k]的理解。
  • kmp的優化(待續。。)
  • 一.什么是kmp

    KMP算法是一種改進的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同時發現,因此人們稱它為克努特——莫里斯——普拉特操作(簡稱KMP算法)。KMP算法的關鍵是利用匹配失敗后的信息,盡量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現一個next()函數,函數本身包含了模式串的局部匹配信息。時間復雜度O(m+n)
    ————來自百度百科
    簡單的說 :
    1.kmp是一種字符串匹配算法。
    2.它的優點就是能通過 next[]數組(一個記憶數組),減少匹配的次數, 從而節省時間。
    3.關鍵是next[] 這個記憶數組。

    二.kmp的額外知識

    由D.E.Knuth,J.H.Morris和V.R.Pratt同時發現,因此人們稱它為克努特——莫里斯——普拉特操作(簡稱KMP算法)
    并且kmp被很多人叫做,看(k)毛(m)片(p)算法。

    三.普通暴力匹配


    //ptr[] 匹配串, str[] 主串

    1.暴力匹配
    我們的普通暴力匹配是 匹配串ptr 的字符一個一個和 主串匹配。
    如果一個字符匹配成功:ptr的下一個字符繼續匹配,
    如果失敗 :str[]回溯到開始匹配的位置(i = i - j, <-下面有講解),然后再以 下一個位置為開始, 再次重新進行字符串匹配。

    暴力匹配代碼:

    int plen = strlen(ptr);//匹配串的長度 int slen = strlen(str);//主串的長度 int i, j = 0; //i 和j 分別代表 當前 str 和ptr 所匹配的字符下標 int flag = 0;//如果為 1 表示 主串中存在 匹配串。 for(i = 0;i < slen;i++) {if(str[i] == ptr[j])//如果匹配成果 繼續下一個匹配{j++;}else//如果 不相等 {i = i- j;//主串回溯, i回到匹配前的位置j = 0;//匹配串 要從頭開始}if(j == plen)// 主串中存在客串 匹配串成功{flag = 1;break;//結束} }

    以上是暴力匹配 的代碼, 這也能解決字符串匹配的問題(這種方法沒有一點錯誤), 然而你用這種方法去解題,很多題只能送你個:

    acmer的你,看到這就是很尷尬了。
    為什么呢?
    因為你暴力匹配太盲目了, 而kmp確實聰明的 kmp的j知道往哪跳。

    四. 相同前后綴的講解:

    1.什么是前后綴。
    如:ABCD這個字符串
    A
    AB
    ABC
    就是他的前綴。

    BCD
    _CD
    __ D
    就是它的后綴。
    ·下劃線只是營造效果, 沒有意義。

    2.相同前后綴:
    如:ABCAB這個字符串
    AB(前綴) AB(后綴) 就是相似前后綴(而且AB是最長的相似前后綴)。

    五.kmp的next數組

    kmp 通過next數組, 保留了ptr(匹配串)以每個字符結尾的子串的 最長相同前后綴的長度。通過next 主串就不用回溯, 只需ptr(匹配串)來回的跳(有想法的跳 o(* ̄︶ ̄ *)o)就行。
    {
    如:1. 主串ABCABCABD 客串ABCABD
    2.當匹配到:
    ABCABCABD
    ABCABD 與其失配。
    但是我們已經匹配了ABCABCABD 這個AB 我們已經知道他匹配,
    所以根據ptr的 前后綴相似的性質(ABCABD), 直接跳到相似前綴的哪里 接著往后匹配。
    所以就要知道next數組怎么獲得。

    }

    那么接下來就看個有圖的栗子(例子): 主串:ABABAC 匹配串: ABAC

    /***next數組的獲取*/ int Get_next() {int plen = strlen(ptr);next[0] = -1;int k = -1;//表示上一次匹配的最長前后綴長度for(i = 0; i < plen; i++){if(k == -1 || ptr[i] == ptr[k])// ptr[i]是后綴的對后一個字符, ptr[k]是前綴的最后一個字符。 k = -1是以第一個字符結尾的子字符串沒有前后綴,因此就要有個操作, 解決 第一個字符串就匹配失敗的情況。{k++;//如果本次匹配成功 , 長度加一next[i+1] = k;//數組儲存}else//不成功{i--;//主串不動k = next[k];//長度縮減再次匹配, 對于k為什么等于next[k] ,后續會有講解。}} } /***kmp 匹配過程****/ int kmp(char str[], char ptr[]{int flag = 0; // flag = 1 表示 主串中含有 匹配串int slen = strlen(str);int plen = strlen(ptr);int i, j = 0;for(i = 0;i < slen;i++){if(j == -1||str[i] == ptr[j])//j == -1是:當第一個字符串就不匹配時, 整個匹配串要整體往右移一個。{j++;}else {i--;j = next[j];//匹配失敗 j 跳到一上一個字母結尾的前綴后面+1處,}if(j == plen){flag = 1;break;}}return flag; }

    六. k = next[k]的理解:

    其他大佬對k = next的理解入口->
    本人的講解:
    當匹配失敗時 主串 i會停留不動,
    k 會都等于 next[k]。

    一下圖片是 AAACAAAA和它next[]數組情況正確

    接下來是過程

    深入了解kmp 請看大牛的講解->

    轉載于:https://www.cnblogs.com/TJack/p/10526956.html

    總結

    以上是生活随笔為你收集整理的KMP算法的学习经验的全部內容,希望文章能夠幫你解決所遇到的問題。

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