推薦學習文章
代碼
public class Main {
public static void main(String[] args) {
//
int i = violenceMatch("我是 我是最 我是最帥的", "我是最帥的");
System.out.println(Arrays.toString(getNext("aabaaf")));
System.out.println(KMP(getNext("aabaaf"),"aabaabaaf","aabaaf"));
}
//求解next數組
public static int[] getNext(String s){//s 是傳進來的模式串
//首先建立next數組
int[] next = new int[s.length()];
//将字元串轉化為數組
char[] chars = s.toCharArray();
//第一個元素為0
next[0] = 0;
//i 是字尾碼的最後一位,j 是字首碼的最後一位
//比如字尾碼是aaf,那麼i就指向f
//比如字首碼是aaf,那麼j就指向f
int j = 0;
for (int i = 1;i < next.length;i++){//i 從1 開始,因為0已經指派了
//如果i和j指向的不相等
//如果不相等,則j要不斷回溯到最終位置(要麼回溯到第一個,要麼回溯到i和j指向的數相等的位置)
//!!! 這裡有一個非常易錯的點,就是j要用while循環進行回溯
//!!! 還有 就是這個一定要放在最前面,不然下面的if無法做事
while (j > 0 && chars[i] != chars[j]){
j = next[j - 1];
}
//如果i和j指向的相等
if (chars[i] == chars[j]){
j++;
}
//然後給next數組指派
next[i] = j;
}
return next;
}
//根據next數組進行KMP
/**
*
* @param next next數組
* @param string1 原字元串
* @param string2 模式串
* @return
*/
public static int KMP(int[] next,String string1,String string2){
if (string1.length() == 0 || string2.length() == 0){
return -1;
}
//首先得到字元數組
char[] bigChars = string1.toCharArray();
char[] smallChars = string2.toCharArray();
//然後定義模式串的索引j
int j = 0;
for (int i = 0;i < bigChars.length;i++){//還是要記住一點,不管是否比對上,i都要++
//如果i和j指向的不相等,j傳回next數組指向的位置(KMP)的精髓
//!!! 這裡有一個非常易錯的點,就是j要用while循環進行回溯
while (j > 0 && bigChars[i] != smallChars[j]){
j = next[j - 1];//這裡直接是next[j]的
}
//如果i和j指向的字元相等
if (bigChars[i] == smallChars[j]){
//i++; 這裡不應該有i++ 因為i++在for循環中有
j++;
}
//循環退出條件(方法傳回條件)
if (j == smallChars.length){
//說明比對到最後了,傳回索引位置
return i - smallChars.length + 1;
}
}
return -1;
}
//暴力比對
public static int violenceMatch(String str1,String str2){
//将字元串轉為字元數組
char[] str1Array = str1.toCharArray();
char[] str2Array = str2.toCharArray();
//定義字元數組的索引
int str1Index = 0;
int str2Index = 0;
while (str1Index < str1Array.length && str2Index < str2Array.length){
//當比對成功的時候,都++
if (str1Array[str1Index] == str2Array[str2Index]){
str1Index++;
str2Index++;
}else {
//比對不成功,包括兩種情況,一是在比對成功之後的失敗,二是一開始就失敗,但都可以用一個公式
str1Index = str1Index - (str2Index - 1);
str2Index = 0;
}
}
if (str2Index == str2Array.length){
//說明找到了
return str1Index - str2Index;
}else {
//沒找到
return -1;
}
}
}
[0, 1, 0, 1, 2, 0]
3