1. 程式人生 > >KMP演算法的nextval陣列

KMP演算法的nextval陣列

nextval陣列是在next陣列缺陷的情況下提出的,例如:模式“aaaab”在和主串"aaabaaaab"匹配時,當i=4,j=4時s.ch[i]!=T.ch[j],由於next[j]=3的指示,會模式串右滑一位進行i=4,j=3的比較,接著有根據next陣列的指示會進行i=4,j=2,i=4,j=1的比較。實際上,因為模式串1~3個字元和第四個字元都相等,因此不需要再和主串中第第四個字元比較,而可以將模式串連續向右滑4個字元的位置直接進行i=5,j=1的比較。

因為next存在上述的問題,所以提出了next陣列的修改值——nextval陣列,nextval陣列的計算方法有兩種:一種是不依賴於next陣列直接觀察得到的,另一種是根絕next陣列進行推了得到的。

首先來分析以下第一種方法:

那“aaaab”做模式串為例:

1、如果第一個字元‘a’在於主串匹配時與主串不匹配則不需要將模式串進行任何滑動直接讓主串下一個位置和模式串第一個位置比較就可以了。所以第一個位置'a'的nextval[1]=0;

2、如果模式串第二個字元'a'在與主串匹配是與主串不匹配,則說明主串當前字元一定不為'a',同時也說明主串的上一個字元一定與模式串的第一個字元匹配一定為‘a’,所以無論模式串怎麼滑動,都不可能與主串當前字元匹配(因為主串當前字元不為'a',而模式串前面的字元都為'a'),所以只能主串下移一位重新與模式串第一位開始比較,所以模式串第二個位置'a'的nextval[2]=0。

3、與2理論相同得到第三位nextval[3]=0

4、與2理論相同得到第四位nextval[4]=0

5、如果模式串第五位‘b’與主串當前字元不匹配,則說明主串當前位置的字元不為'b',同時也說明主串前面四位都為‘a’,因為主串當前位置不為‘b’,則說明主串當前位置可能為'a',又因為模式串前四位都為‘a’,所以可以把模式串向右滑一位使模式串第四位‘a’與主串當前位置字元相比較。因為主串當前位置的前4位都為‘a’,說明主串的當前位置的前三位與模式串的前三位相同,所以模式串第五位置'b'的nextval[5]=4.

 1  2  3  4  5  6
 a
 a  a  a  *  *
 a  a  a  a  b
 a  a  a  a  b

再舉一個例子:“abaabcac”

1、如果模式串第一位'a'與主串當前字元不匹配,則不需要滑動了,直接主串後移一位與模式串第一位比較即可.所以模式串第一位'a'的nextval[1]=0。

2、如果模式串第二位‘b’與主串當前字元不匹配,則說明主串當前字元不為'b',主串當前字元的前一位一定與模式串第一位匹配為'a'。主串第二位不為'b',則可能為'a',所以可以將模式串向有滑動一位,讓主串當前位置與模式串第一位進行比較,因此模式串第二位‘b’,nextval[2]=1.

3、如果模式串第三位‘a’與主串當前位置字元不匹配,則說明主串當前位置字元不為'a',同時也說明主串當前位置的前兩個字元與模式串的前兩個字元匹配位“ab”。因為第三個字元不為'a',則說明第三個字元可能位'b',如果為'b'則可以讓模式串想右滑動一位讓模式串第二位與主串當前位置比較,但是這樣以來模式串第一位'a'就會與主串前一位'b'進行比較,明顯不匹配,所以模式串這樣滑動不可以,可以看到模式串前面兩位'ab"不論怎麼樣都不能與主串當前位置匹配,所以只能讓主串下移一位與模式串第一位開始比較。所以模式串第三位'a'的nextval[3]=0.

4、如果模式串第四位‘a’與主串當前位置字元不匹配,則說明主串當前位置不為'a',同時也說明主串當前位置的前三個位置與模式串前三個匹配為"aba"。因為主串當前位置不為'a',所以可能為'b',如果為'b',可以讓模式串向右滑動兩位,使模式串第二位‘b’與主串當前位置進行比較,這樣模式串的第一個位置會和主串當前位置的前一個比較,顯然都為'a',匹配。所以模式串第四位‘a’的nextvak[4]=2。

5、如果模式串的第五位‘b’與主串當前位置不匹配,則說明主串當前位置字元不為'b',同時也說明主串當前位置的前四位與模式串的前四位匹配人,為“abaa”。因為主串當前位置不為'b',所以可能為‘a’.如果為‘a’,則可以讓模式串向右滑動一位,使模式串第四位與主串當前字元比較,但是此時還需要模式串前三"aba"位與主串當前位置的前三位“baa”匹配,顯然是不匹配的所以這樣滑動不可以;還可以模式串向右滑動兩位,讓模式串第三位與主串當前位置進行比較,但是此時模式串前兩位'ab'與主串當前位置的前兩位‘aa’不匹配,所以這樣滑動也不可以;因為主串當前位置不為'b',所以不能右滑三位讓模式串第二位與主串當前位置比較;模式串右滑四位,讓模式串第一為'a'與主串當前位置比較,模式串前沒有字元了,所以這樣滑動可以。綜上,模式串第五位‘b’的nextval[5]=1。

6、