1. 程式人生 > >算法思想

算法思想

長度 例子 ati new || urn 字符串 length pub

1、KMP算法

設有兩串字符,第一串為主串,第二串為副串,求副串在主串的匹配index頭。

主要是求next數組,感性認識是副串的前後綴匹配程度:

- "A"的前綴和後綴都為空集,共有元素的長度為0;

  - "AB"的前綴為[A],後綴為[B],共有元素的長度為0;

  - "ABC"的前綴為[A, AB],後綴為[BC, C],共有元素的長度0;

  - "ABCD"的前綴為[A, AB, ABC],後綴為[BCD, CD, D],共有元素的長度為0;

  - "ABCDA"的前綴為[A, AB, ABC, ABCD],後綴為[BCDA, CDA, DA, A],共有元素為"A",長度為1;

  - "ABCDAB"的前綴為[A, AB, ABC, ABCD, ABCDA],後綴為[BCDAB, CDAB, DAB, AB, B],共有元素為"AB",長度為2;

  - "ABCDABD"的前綴為[A, AB, ABC, ABCD, ABCDA, ABCDAB],後綴為[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的長度為0。

public static int KMP(String ts, String ps) {

    char[] t = ts.toCharArray();

    char[] p = ps.toCharArray();

    
int i = 0; // 主串的位置 int j = 0; // 模式串的位置 int[] next = getNext(ps); while (i < t.length && j < p.length) { if (j == -1 || t[i] == p[j]) { // 當j為-1時,要移動的是i,當然j也要歸0 i++; j++; } else { // i不需要回溯了 // i = i - j + 1; j
= next[j]; // j回到指定位置 } } if (j == p.length) { return i - j; } else { return -1; } } public static int[] getNext(String ps) { char[] p = ps.toCharArray(); int[] next = new int[p.length]; next[0] = -1; int j = 0; int k = -1; while (j < p.length - 1) { if (k == -1 || p[j] == p[k]) { if (p[++j] == p[++k]) { // 當兩個字符相等時要跳過 next[j] = next[k]; } else { next[j] = k; } } else { k = next[k]; //如果不相等,則next設為0;舉個例子,ABCD,這字符串的前後綴都不一樣,則next[]=-1,0,0,0,0
//而ABCDABD,這字符串前後綴存在相同,即其中的AB,則next[]=-1,0,0,0,0,1,2,0 } }
return next; }

算法思想