參考網址
https://www.youtube.com/watch?v=GTJr8OvyEVQ
https://blog.csdn.net/christ1750/article/details/51259425
B站視頻目前正在審覈,所以提供下我的B站賬號: 少年的神 沒法訪問的可以去我B站視頻找下。
構建前綴表
最主要的還是要構建一個前綴表,然後在匹配錯誤的地方按照上一個字母前綴表的下標再去判斷是否相等,相等則前綴表+1作爲其前綴,不相等則再取其前綴表往前直到第一個比較不相等後則前綴表賦值爲0。(注意最後一個的前綴)
比較目標字符串是否在當前字符串中
其實就是循環當前字符串,噹噹前字符串值第一次等於目標字符串的第一個字母時開始比對下一個,如果下一個不相等就取其前一個的前綴表對應的值再對比,直到相等。
代碼
用來存放值的實體類
public class Enity { private char x; private int index;
public char getX() { return x; }
public void setX(char x) { this.x = x; }
public int getIndex() { return index; }
public void setIndex(int index) { this.index = index; }
@Override public String toString() { return "值爲"+getX()+"==========="+getIndex()+"\n"; } } |
實現KMP算法的工具類
import java.util.ArrayList; import java.util.List;
public class KmpUtil { private KmpUtil(){
}
/** * * @param s 需要得到前綴表的字符串 * @return * j i * S a b c d * (index) 0 0 */ public static List<Enity> getPreTable(String s){ List<Enity> result = new ArrayList<>(); char[] strs=s.toCharArray(); // 將值賦值到對應的實體類 for (int i=0;i<s.length();i++){ Enity enity = new Enity(); enity.setX(strs[i]); result.add(enity); } //此處開始給實體配置前綴表 result.get(0).setIndex(0); int j=0; for(int i=1;i<result.size();i++){ // 這裏獲取j值得方法是獲取前一個的前綴表值, // 如果和i的值還是不等就再取前一個的前綴值, // 直到相等後取j+1作爲前綴值。或者j=0後依然 // 不相等則取前綴值爲0 while (j>0&&result.get(j).getX()!=result.get(i).getX()){ j=result.get(j-1).getIndex(); } if (result.get(j).getX()==result.get(i).getX()){ j++; } result.get(i).setIndex(j);
} System.out.println("得到的前綴表:\n"); System.out.println(result.toString()); return result; }
/** * * @param str 判斷是否包含dest的字符串 * @param dest 目標字符串 * @return * * i * str a b c d * * destr b c * (index)j */ public static boolean isInclude(String str,String dest){ System.out.println("開始進行對比"); char[] strs=str.toCharArray(); List<Enity> resultList = getPreTable(dest); for (int i=0,j=0;i<str.length();i++){ /** * 這裏和上面一個循環差不多 */ while(j>0&&strs[i]!=resultList.get(j).getX()){ j=resultList.get(j-1).getIndex(); } if(strs[i]==resultList.get(j).getX()){ j++; } //如果j等目標字符串長度說明已經全部比對過一遍說明有該值存在 if (j==dest.length()){ return true; //如果還想要繼續比對看是否還有 // 這裏將j設置爲最後一個的前綴值就可以繼續獲取下一個符合的位置 } } return false; }
} |
測試方法
System.out.println(KmpUtil.isInclude("fabadfadsfadfa","&")); |