KMP演算法的程式碼實現
阿新 • • 發佈:2018-12-02
以下程式碼為第一步求最大前後綴所含字元個數的程式碼:
首先我們明確:next[i]存放的是前i個字元組成的字串的最大相同前後綴長度
1 public static int[] kmpnext(String str){ //引數為要求的字串str 2 int[] next = new int[str.length()]; //新建一個next陣列,每一位存放對應的前n位組成的子字串的最大前後綴相同元素個數 3 next[0] = 0; //第一位沒有前後綴,故為04 for(int i = 1,j = 0; i < str.length(); i++){ //從第二位開始,依次求出所求的值 5 while(j > 0 && str.charAt(j) != str.charAt(i)){ //重要,下面詳細解釋此處 6 j = next[j - 1]; 7 } 8 if(str.charAt(i) == str.charAt(j)){ //上一輪迴圈已經比較過了前j位與後j位相同,此時若第j+1位,即索引位j的值與索引為i的值相同,那麼在這一輪迴圈中,新字串的最大前後綴就是上一輪的+19 j++; 10 } 11 next[i] = j; //將所求的值j存放到對應位置 12 } 13 return next; 14 }
while(j>0 && str.charAt(j) != str.charAt(i))的意思是:
此時j的值為上一輪迴圈當中存放在next[i]中的值,即上一輪迴圈中前i位的最大前後綴的值,
此時迴圈+1,即比較新增加的一位與字首中新增加的一位是否相等,相等的話執行j++
不等的話執行j=next[j-1];
j=next[j-1]是這段程式碼中最難理解的部分,下面為解釋:
此時發現charAt(j) != cjarAt(i),我們將目光放在索引為j之前的子字串中:
改變了j的值後,圖示的兩塊橘色矩形為相同序列,
我們再比較新位置上的charAt(j)與charAt(i)是否相等即可,如果不相等則利用j=next[j-1]繼續縮小j的值。