kmp算法中的nextval實例解釋


求nextval數組值有兩種方法,一種是不依賴next數組值直接用觀察法求得,一種方法是根據next數組值進行推理,兩種方法均可使用,視更喜歡哪種方法而定。

本文主要分析nextval數組值的第二種方法
  a b a a b c a c   模式值
  0 1 1 2 2 3 1 2 next數組
  0 1 0 2 1 3 0 2 nextval數組

  1.第一位的nextval值必定為0,第二位如果於第一位相同則取相同值下的next值為0,如果不同則取當下next的值為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。

三、next和nextval比較

Next數組的缺陷舉例如下:

比如主串是“aab…..”  省略號代表后面還有字符。

 模式串“aac”

通過計算aac的next數組為012(另外,任何字符串的第二位字符的next總是1,因此你可以認為他固定為1)

當模式串在字符c上失配時,會跳到第2個字符,然后再和主串當前失配的字符重新比較,即此處用模式串的第二個a和主串的b比較

即 aab                   aac

顯然a也不等於b。然后 會跳到1,接着比,然后又失配,直到最后才使主串后移一位。

而“aac”的nextval數組為002 當在c失配時會跳到2,若還失配就直接跳到0,比next數組少比較了1次。

在如果模式串很長的話,那可以省去很多比較,因此你應該使用nextval數組。

 

四、嚴蔚敏

上:http://v.youku.com/v_show/id_XODYxNjExODQ=.html     第 34分鍾開始 

    下:http://www.56.com/u28/v_NjAwMzA0ODA.html     

五、代碼實現:
    public static void main(String [] args) throws IOException{//main函數,輸入主串和模式串
        System.out.print("請輸入主串:");
        Scanner sn1 = new Scanner(System.in);
        String s1 = sn1.next();
        System.out.print("請輸入模式串:");
        Scanner sn2 = new Scanner(System.in);
        String s2 = sn2.next();
        char [] s3 = s1.toCharArray();
        char [] s4 = s2.toCharArray();
        System.out.print(KMP_test(s3,s4));
    }
    
    public static int KMP_test(char [] s, char [] t){// 主串順序匹配
        int [] next = next(t);
        int i = 0, j = 0;
        while(i
            if(j == -1 || s[i] == t[j]){
                ++i;
                ++j;
            }else{
                j = next[j];
            }
        }
        System.out.println(i);
        if(j
            return 0;
        }else{
            return i-t.length;
        }
    }
    
    public static int [] next(char [] t){// next函數求解
        int i = 0, j = -1;
        int [] next = new int[t.length];
        next[0] = -1;
        while(i
            if(j == -1 || t[i] == t[j]){
                ++i;
                ++j;
                next[i] = j;
            }
            else
                j = next[j];
        }
        System.out.println(Arrays.toString(next));
        return next;
    }
對於改進的KMP算法,只需要把next函數換為nextval函數就行了
    public static int [] next(char [] t){
        int i = 0, j = -1;
        int [] next = new int[t.length];
        next[0] = -1;
        while(i
            if(j == -1 || t[i] == t[j]){
                ++i;
                ++j;
                if (t[i] != t[j]) {  
                    next[i] = j;  
                } else {  
                    next[i] = next[j];  
                } 
            }
            else
                j = next[j];
        }
        System.out.println(Arrays.toString(next));
        return next;
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM