1. 程式人生 > >字串匹配KMP演算法中Next[]陣列求法

字串匹配KMP演算法中Next[]陣列求法

int get_nextval(SString T,int &nextval[ ]){
           //求模式串T的next函式修正值並存入陣列nextval。
           i=1; nextval[1]=0; j=0;
           while(i<T[0]){
               if(j==0||T[i]==T[j]){
                   ++i;++j;
                   if (T[i]!=T[j]) nextval[i]=j;
                   else nextval[i]=nextval[j];
               }
               else j=nextval[j];
           }
       }//get_nextval
       根據這段程式來求nextval的值是可以方便計算出來,但如果是應付考研試題或者期末考試就有點麻煩了。而如果記住我推薦的方法,那麼任何時候都可以很 方便地求解nextval了。
       首先看看next陣列值的求解方法

       例如:
模式串 a b a a b c a c
     next值 0 1 1 2 2 3 1 2
     nextval值
       next陣列的求解方法是:第一位的next值為0,第二位的next值為1,後面求解每一位的next值時,根據前一位進行比較。首先將前一位與其 next值對應的內容進行比較,如果相等,則該位的next值就是前一位的next值加上1;如果不等,向前繼續尋找next值對應的內容來與前一位進行 比較,直到找到某個位上內容的next值對應的內容與前一位相等為止,則這個位對應的值加上1即為需求的next值;如果找到第一位都沒有找到與前一位相 等的內容,那麼需求的位上的next值即為1。
       看起來很令人費解,利用上面的例子具體運算一遍。
       1.前兩位必定為0和1。
       2.計算第三位的時候,看第二位b的next值,為1,則把b和1對應的a進行比較,不同,則第三位a的next的值為1,因為一直比到最前一位,都沒有 發生比較相同的現象。
       3.計算第四位的時候,看第三位a的next值,為1,則把a和1對應的a進行比較,相同,則第四位a的next的值為第三位a的next值加上1。為 2。因為是在第三位實現了其next值對應的值與第三位的值相同。
       4.計算第五位的時候,看第四位a的next值,為2,則把a和2對應的b進行比較,不同,則再將b對應的next值1對應的a與第四位的a進行比較,相 同,則第五位的next值為第二位b的next值加上1,為2。因為是在第二位實現了其next值對應的值與第四位的值相同。
       5.計算第六位的時候,看第五位b的next值,為2,則把b和2對應的b進行比較,相同,則第六位c的next值為第五位b的next值加上1,為3, 因為是在第五位實現了其next值對應的值與第五位相同。
       6.計算第七位的時候,看第六位c的next值,為3,則把c和3對應的a進行比較,不同,則再把第3位a的next值1對應的a與第六位c比較,仍然不 同,則第七位的next值為1。
       7.計算第八位的時候,看第七位a的next值,為1,則把a和1對應的a進行比較,相同,則第八位c的next值為第七位a的next值加上1,為2, 因為是在第七位和實現了其next值對應的值與第七位相同。
       在計算nextval之前要先弄明白,nextval是為了彌補next函式在某些情況下的缺陷而產生的,例如主串為“aaabaaaab”、模式串為 “aaaab”那麼,比較的時候就會發生一些浪費的情況:比較到主串以及模式串的第四位時,發現其值並不相等,據我們觀察,我們可以直接從主串的第五位開 始與模式串進行比較,而事實上,卻進行了幾次多餘的比較。使用nextval可以去除那些不必要的比較次數。
       求nextval陣列值
有兩種方法,一種是不依賴next陣列值直接用觀察法求得,一 種方法是根據next陣列值進行推理,兩種方法均可使用,視更喜歡哪種方法而定。
       我們使用例子“aaaab”來考查第一種方法
       1.試想,在進行模式匹配的過程中,將模式串“aaaab”與主串進行匹配的時候,如果第一位就沒有吻合,即第一位就不是a,那麼不用比較了,趕快挪到主 串的下一位繼續與模式串的第一位進行比較吧,這時,模式串並沒有發生偏移,那麼,模式串第一位a的nextval值為0。
       2.如果在匹配過程中,到第二位才發生不匹配現象,那麼主串的第一位必定是a,而第二位必定不為a,既然知道第二位一定不為a,那麼主串的第一、二兩位就 沒有再進行比較的必要,直接跳到第三位來與模式串的第一位進行比較吧,同樣,模式串也沒有發生偏移,第二位的nextval值仍然為0。
       3.第三位、第四位類似2的過程,均為0。
       4.如果在匹配過程中,直到第五位才發生不匹配現象,那麼主串的第一位到第四位必定為a,並且第五位必定不為b,可是第五位仍然有可能等於a。如果萬一第 五位為a,那麼既然前面四位均為a,所以,只要第六位為b,第一個字串就匹配成功了。所以,現在的情況下,就是看第五位究竟是不是a了。所以發生了下面 的比較:
1
2 3 4 5 6
a a a a * *
a a a a b
a a a a b

       前面的三個a都不需要進行比較,只要確定主串中不等於b的那個位是否為a,即可以進行如下的比較:如果為a,則繼續比較主串後面一位是否為b;如果不為 a,則此次比較結束,繼續將模式串的第一位去與主串的下一位進行比較。由此看來,在模式串的第五位上,進行的比較偏移了4位(不進行偏移,直接比較下一位 為0),故第五位b的nextval值為4。
       我們可以利用第一個例子“abaabcac”對這種方法進行驗證。
       a的nextval值為0,因為如果主串的第一位不是a,那麼沒有再比較下去的必要,直接比較主串的第二位是否為a。如果比較到主串的第二位才發生錯誤, 則主串第一位肯定為a,第二位肯定不為b,此時不能直接跳到第三位進行比較,因為第二位還可能是a,所以對主串的第二位再進行一次比較,偏移了1位,故模 式串第二位的nextval值為1。以此類推,nextval值分別為:01021302。其中第六位的nextval之所以為3,是因為,如果主串比較 到第六位才發生不匹配現象,那麼主串的前五位必定為“abaab”且第六位必定不是“c”,但第六位如果為“a”的話,那麼我們就可以從模式串的第四位繼 續比較下去。所以,這次比較為:

1 2 3 4 5 6 7 8 9 10 11 12
a b a a b * * * * * * *
a b a a b c a c

       而不是:
1 2 3 4 5 6 7 8 9 10 11 12
a b a a b * * * * * * *
a b a a b c a

       因為前兩位a和b已經確定了,所以不需要再進行比較了。所以模式串第六位的nextval值為這次比較的偏移量3。
       再來看求nextval陣列值的第二種方法
模式串 a b a a b c a c
next值 0 1 1 2 2 3 1 2
nextval值 0 1 0 2 1 3 0 2

       1.第一位的nextval值必定為0,第二位如果於第一位相同則為0,如果不同則為1。
       2.第三位的next值為1,那麼將第三位和第一位進行比較,均為a,相同,則,第三位的nextval值為0。
       3.第四位的next值為2,那麼將第四位和第二位進行比較,不同,則第四位的nextval值為其next值,為2。
       4.第五位的next值為2,那麼將第五位和第二位進行比較,相同,第二位的next值為1,則繼續將第二位與第一位進行比較,不同,則第五位的 nextval值為第二位的next值,為1。
       5.第六位的next值為3,那麼將第六位和第三位進行比較,不同,則第六位的nextval值為其next值,為3。
       6.第七位的next值為1,那麼將第七位和第一位進行比較,相同,則第七位的nextval值為0。
       7.第八位的next值為2,那麼將第八位和第二位進行比較,不同,則第八位的nextval值為其next值,為2。
       在“aaaab”內進行驗證。
模式串 a a a a b
next值 0 1 2 3 4
nextval值 0 0 0 0 4

相關推薦

字串匹配KMP演算法Next[]陣列求法

int get_nextval(SString T,int &nextval[ ]){            //求模式串T的next函式修正值並存入陣列nextval。            i=1; nextval[1]=0; j=0;            while(i<T[0]){

字串匹配——KMP演算法next陣列理解

關於原理就不講了,只說下我對Next陣列的理解,希望可以讓你獲得靈光一閃。 其實最難的就是是j=Next[j];這麼一句話,當時思考了很長時間,終於明白的時候確實很興奮加得意。 #include<cstdio> #include<cstring> v

關於KMP演算法next陣列和nextVal陣列求法的整理

例如: 序號 1 2 3 4 5 6 7 8 模式串 a b a a b c a c next值 0 1 1 2 2 3 1 2 next陣列的求解方法是:     第一位的next值為0,第二位的next值為1,後面求解每一位的next值時,根據前一位進行比較。

關於kmp演算法next陣列求法【針對手算的】

 關於kmp演算法中next陣列的求法【手算版本】 本篇只介紹next的求法和nextval的求法   例如  模式串:a b c d c a b c d s a c          next

KMP演算法next陣列、nextval陣列的手工計算

剛接觸資料結構,對於其中的一些演算法都不是很瞭解,這幾天剛在學習串的內容,裡面介紹了兩種串的模式匹配演算法,一種是BF演算法(也叫做BoyFriend演算法);另一種是KMP演算法(也叫做“看毛片”演算法)。BF演算法的實現很簡單,很暴力,但是在時間複雜度的限制下,這不是一個

KMP演算法next陣列的手工計算方法

筆試題目中經常要求計算KMP演算法的next陣列,網上有很多討論的文章,但是感覺都講的不太清楚,特別是在如何手工計算這一方面,所以今天特別整理了一下放到這裡,一來備忘,二來也希望給有緣人帶來一些方便。 位置編號 1 2 3 4 5

KMP演算法next陣列與字首的週期(相關題目:Power strings, poj2406)

在一個大的字串S中查詢字串T,naive的演算法時間複雜度為O(s * t)(這裡s與t代表S的長度與T的長度);而應用KMP,時間複雜度為O(s + t)。 KMP演算法的核心在於next陣列。next陣列只與字串T有關,與S無關。 next陣列的核心思想是儲存字串T

KMP演算法next和nextval陣列的計算方法

設字串S=’aabaabaabaac’P=’aabaac’ 1.給出S和P的next值和nextvai值; 2.若S作主串,P為模式串,試給出利用BF演算法和KMP演算法的匹配過程. 答:1.給出S和P的next值和nextvai值; 失效函式採用的是清華殷人昆的資料結構上的

kmp演算法 關於next陣列的詳細解釋

前言     之前對kmp演算法雖然瞭解它的原理,即求出P0···Pi的最大相同前後綴長度k;但是問題在於如何求出這個最大前後綴長度呢?我覺得網上很多帖子都說的不是很清楚,總感覺沒有把那層紙戳破,後來翻看演算法導論,32章 字串匹配雖然講到了對前後綴計算的正確性,但

字串匹配 & KMP演算法

初識KMP 期末的時候學習了KMP演算法,雖然一開始的確聽得是一頭霧水,但是到現在,已經基本懂得了其中的原理,於是在這裡把自己的理解寫出來,再配上自己做的圖示,希望對大家的學習有幫助,要是有什麼疑問或建議,歡迎留言評論。^-^ KMP是一種用於字串匹配的

KMP演算法next陣列詳解

    最近整理筆記時,突然翻出幾年前理解起來困難無比的看毛片(KMP)演算法,筆記中詳述了搜尋過程,圖文並茂,然而在最最重要的next陣列部分卻是一帶而過,於是找出當年的教材,也只是寫了getnext()函式,想著上網找一找圖文並茂的舉例,結果這一找徹底蒙比,眾說紛紜,同

最簡單的KMP演算法next陣列值的方法

本文依照嚴蔚敏串的資料結構(C語言版本)總結的方法: next陣列的求解方法是: 注意:1.   j的下標識從0開始排的                 2.  規定next[0]=-1,next[1]=0                   j           

字串匹配——KMP演算法的Java實現

開始複習演算法,複習到字串這一結構時,一個經典的問題就是兩個字串的匹配問題。 比如:在主串ssdfgasdbababa中找是否存在一個asdba的子串。 傳統方法——暴力匹配 用傳統的方法就是暴力匹配,從主串中一個個地和子串匹配。 最壞的情況下,就是

面向考研——計算KMP演算法next陣列和nextval陣列

KMP演算法中,如何手動求next陣列和nextval陣列? 首先我們要理解next陣列的意義,為了實現更加高效的字元匹配,next陣列是用來尋找字串陣列內部的自身的一種規律,利用字串內部的一種相似性,來優化字串陣列匹配演算法。所以才需要計算這麼一個next陣列來幫助演算法

資料結構KMP演算法課本上的next陣列和nextval陣列求解方法

next陣列的求解方法是:第一位的next值為0,第二位的next值為1,後面求解每一位的next值時,根據前一位進行比較。首先將前一位與其next值對應的內容進行比較,如果相等,則該位的next值就是前一位的next值加上1;如果不等,向前繼續尋找next值對應的內容來與前

KMP演算法關於next陣列的j=next[j]理解

這篇文章是在oneNote上寫的,小弟不懂oneNote怎麼轉成md,所以只能笨辦法截圖上來了。。。覺得看的費勁的可以找我要原本 聯絡方式郵箱: [email protected]

KMP模式匹配演算法next和nextval的求解(轉)

KMP演算法相關 轉載自:http://blog.sina.com.cn/s/blog_85b0ae450101j2iy.html KMP演算法由兩部分組成: 第一部分,計算模式串的next或nextval陣列。 第二部分,利用計算好的模式串的nextval陣列,進行模式

KMP模式匹配演算法next,nextval的分別實現

next陣列定義: 對於這個定義,我的理解是從1~j-1中,字首與字尾有n個相等,則next[j]=n+1。 例如:t="abcabaa" 當j=1時,next[1]=0。 當j=2時,從1~j-1,串為a,next[2]=1。 當j=3時,從1~j-1,串為ab,nex

KMPnext陣列定義

KMP演算法的Next陣列詳解 轉載請註明來源,幷包含相關連結。 網上有很多講解KMP演算法的部落格,我就不浪費時間再寫一份了。直接推薦一個當初我入門時看的部落格吧: http://www.cnblogs.com/yjiyjige/p/3263858.html 這位同學用詳細的

字串匹配 KMP演算法分析

圖片來源於  土豆洋芋山藥蛋 https://blog.csdn.net/qq_33414271/article/details/83789478 1.什麼是KMP演算法? 在主串Str中查詢模式串Pattern的方法中,有一種方式叫KMP演算法 KMP演算法是在模式