咳咳咳,這是看毛片算法的簡單介紹
首推一個博客,這個博客很優秀,我的KMP算法就是從上面學來的——https://www.cnblogs.com/yjiyjige/p/3263858.html
算法思想
假設母串是BACAACAAADH,子串是ACAACAD,
當匹配到下圖一步,指針i和j的位置明顯不匹配了,
腫麼辦,按照暴力的辦法應該是把指針i和j回溯到如下圖的位置再比較
但是,我們發現這樣時間複雜度就變得很不友好,
細心或者對KMP有接觸的朋友應該注意到了其實可以不回溯這麼遠,
其實可以回溯到如下圖的位置
爲什麼呢,因爲在子串中存在前三個字符和接下來的三個字符相同,
這樣,我們就可以保持i指針不變,將j指針回溯三個字符,然後接着繼續進行匹配操作,
從這個例子可以看出子串中有可能存在和開頭相等的子子串,式子表示如下
str.substring(0, k) = str.substring(m, n)
我們可以利用這個特性,減少已經匹配過的串儘量少的回溯
咳咳咳,先想清楚再看下面的,如果想不太明白,那也看看下面的,
下面的是重點,考試要考的
++++++++++++++++++++++++++華麗的分割線++++++++++++++++++++++++++++
弄明白KMP的主體思想思想之後,我們就開始關注怎麼實現了,
首先先看一個例子,如果當出現如下匹配失敗的時候
因爲橙色區域的和黃色區域的已經確認匹配,並且存在相等的情況,
所以回溯的時候,可以保持指針i不變,將指針j回溯到黃色區域的開頭那裏,如下圖
也就是下圖
也就是回溯到的位置是下標爲3的位置,從這個例子可以看出,
在母、子串匹配的時候,無論在哪個位置不匹配,都會存在一個回溯的值,
哪怕是第一個就不匹配,也可以回溯到-1的位置。
下面那個就是對應位置回溯位置的數組
對於ACAACAD這個子串來說,其數組爲
關於代碼怎麼實現的,這個目前比較流行的是我下面給出的代碼,
這個代碼有兩個難點,一個是k = next[k],一個j–
結合我給的例子,慢慢揣摩就能明白,我抽象表達能力不太好,這裏就不誤導大家了,
大家也可以去看看我開頭推薦的那個博客,ta寫的挺詳細的,但是我沒看(主要是太笨了,不想看也看不懂),我都是看ta代碼慢慢研究出來的
上代碼
// 暴力匹配的算法,至於怎麼暴力,反正就是暴力,不要在意這些細節嘛
public int indexOf(String origin, String subStr) {
int result = -1;
for (int i=0; i<origin.length()-subStr.length(); i++) {
boolean matching = true;
for (int j=0; j<subStr.length(); j++) {
if (origin.charAt(i+j) != subStr.charAt(j)) {
matching = false;
break;
}
}
if (matching) {
result = i;
break;
}
}
return result;
}
// KMP算法的實現
public int indexOf(String origin, String subStr) {
int result = -1;
int i, j;
i = j = 0;
int[] next = getNext(subStr);
while (i < origin.length()) {
// 相等的情況
if (subStr.charAt(j) == origin.charAt(i)) {
i++;
j++;
if (j == subStr.length()) {
result = i - j;
break;
}
} else { // 不等的情況
j = next[j];
if (j == -1) {
i++;
j = 0;
}
}
}
return result;
}
// 獲取next數組
public int[] getNext(String str) {
int[] next = new int[str.length()];
int k = next[0] = -1;
// 其它博客都是while循環,這裏爲了體現j--這個的功能,就不用while了
for (int j=1; j<str.length(); j++) {
if (-1 == k || str.charAt(j-1) == str.charAt(k)) { // 第一次k不等於-1的時候是j=2的時候
next[j] = ++k;
} else { // ACAACADH
k = next[k];
j--; // 懂了這個就懂了整個算法
}
}
return next;
}
時間複雜度
O(m+n)
這個博主很懶,就寫了這麼多,並且博主智商捉急,腫麼辦,挺急的單就不在線等了,忙着找藥,有事留言