diff --git a/src/dataANDcalc/java/algorithm/KMP.java b/src/dataANDcalc/java/algorithm/KMP.java new file mode 100644 index 0000000..cd96efa --- /dev/null +++ b/src/dataANDcalc/java/algorithm/KMP.java @@ -0,0 +1,124 @@ +package algorithm; + +import java.util.ArrayList; + +public class KMP { + + private String searchStr; + + private String targetStr; + + private String[] strMatchs; + + private int[] postMatchs; + + private ArrayList prefixs; + + private ArrayList suffixs; + + public KMP(String searchStr, String targetStr){ + this.searchStr = searchStr; + this.targetStr = targetStr; + prefixs = new ArrayList<>(); + suffixs = new ArrayList<>(); + strMatchs = new String[targetStr.length()]; + postMatchs = new int[targetStr.length()]; + for(int i = 0; i 0; i--){ + prefixSuffixMatchs(i); + } + } + + private void makeMatchsOp(){ + for(int i = 1, j = 0; i < targetStr.length(); i++){ + //当targetStr.charAt(i) != targetStr(j) , 需要从postMatchs[j - 1]获取新的j , 直到发现有相等的才退出 + while(j > 0 && targetStr.charAt(i) != targetStr.charAt(j)){ + // 为什么获取新的j是postMatchs[j-1]呢?? + j = postMatchs[j - 1]; + } + if(targetStr.charAt(i) == targetStr.charAt(j)){ + j++; + } + postMatchs[i] = j; + } + } + + private int kmpSearch(){ + int index = 0; + int j = 0; + while(index < searchStr.length()){ + String searchChar = searchStr.substring(index, index+1); + String targetChar = strMatchs[j]; + if (!searchChar.equals(targetChar)){ + if (j == 0){ + index ++ ; + } else { + int suffixPost = j - postMatchs[j - 1]; + index = index + suffixPost; + j = 0; + } + }else { + if (j == strMatchs.length - 1){ + return index - j; + } + index ++; + j ++; + } + } + return -1; + } + + private void show(){ + System.out.println("前缀表"); + for(String prefix : prefixs){ + System.out.print(prefix + " "); + } + System.out.println(); + System.out.println("后缀表"); + for(String suffix : suffixs){ + System.out.print(suffix + " "); + } + System.out.println(); + System.out.println("字符串表:"); + for(String str : strMatchs){ + System.out.print(str + " "); + } + System.out.println(); + System.out.println("部分匹配表:"); + for(int post : postMatchs){ + System.out.print(post + " "); + } + } + + public static void main(String[] args) { + String searchStr = "BBC ABCDAB ABCDABCDABDE"; + String targetStr = "ABCDABD"; + KMP kmp = new KMP(searchStr, targetStr); + kmp.makeMatchs(); + kmp.show(); + System.out.println("找到匹配的字符串位置:"+kmp.kmpSearch()); + } +}