1. 程式人生 > >子字串查詢

子字串查詢

1 暴力破解

 

java實現如下:

 1 public class Naive {
 2 
 3     /**
 4      * 暴力破解
 5      *
 6      * @param pat
 7      * @param txt
 8      * @return
 9      */
10     private static int search(String pat, String txt) {
11         int m = pat.length();
12         int n = txt.length();
13         for
(int i = 0; i <= n - m; i++) { 14 int j; 15 for (j = 0; j < m; j++) { 16 if (txt.charAt(i + j) != pat.charAt(j)) { 17 break; 18 } 19 } 20 if (j == m) { 21 return i; 22 }
23 } 24 return n; 25 } 26 27 public static void main(String[] args) { 28 int pos = search("abcabd", "abcabcabdabba"); 29 System.out.println(pos); 30 } 31 32 }

 最壞的情況是:

常見的是二進位制情況下的匹配:

 

 

 

2 KMP演算法

如果用暴力方法解決的話就會有大量的回溯,每次只移動一位,若是不匹配,移動到下一位接著判斷,浪費了大量的時間:

 

所以,kmp方法演算法就利用之前判斷過資訊,通過一個next陣列,儲存模式串中前後最長公共子序列的長度,每次回溯時,通過next陣列找到,前面匹配過的位置,省去了大量的計算時間。

 1 public class KMP {
 2     public static int KMP(String pat, String txt) {
 3         char[] t = pat.toCharArray();
 4         char[] p = txt.toCharArray();
 5 
 6         int i = 0; // 主串的位置
 7         int j = 0; // 模式串的位置
 8         int[] next = getNext(txt);
 9 
10         while (i < t.length && j < p.length) {
11             if (j == -1 || t[i] == p[j]) { // 當j為-1時,要移動的是i,當然j也要歸0
12                 i++;
13                 j++;
14             } else {
15                 // i不需要回溯了
16                 // i = i - j + 1;
17                 j = next[j]; // j回到指定位置
18             }
19         }
20 
21         if (j == p.length) {
22             return i - j;
23         } else {
24             return -1;
25         }
26     }
27 
28     public static int[] getNext(String ps) {
29         char[] p = ps.toCharArray();
30         int[] next = new int[p.length];
31         next[0] = -1;
32 
33         int j = 0;
34         int k = -1;
35         while (j < p.length - 1) {
36             if (k == -1 || p[j] == p[k]) {
37                 next[++j] = ++k;
38             } else {
39                 k = next[k];
40             }
41         }
42         return next;
43     }
44 
45     public static void main(String[] args) {
46         String pat = "abcabd";
47         String txt = "abcabcabdabba";
48         int pos = KMP(pat, txt);
49         System.out.println(pos);
50     }
51 
52 }

 

kmp演算法的核心時間複雜度就是O(m+n)