2025-01-25 KMP算法-查找字符串问题

This commit is contained in:
liangjinglin 2025-01-25 21:36:44 +08:00
parent 3b53efd9a0
commit d11a8f629c

View File

@ -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<String> prefixs;
private ArrayList<String> 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<targetStr.length(); i++){
strMatchs[i] = targetStr.substring(i, i+1);
}
}
private void prefixSuffixMatchs(int length){
for(int i = 1; i<length; i++){
String prefix = targetStr.substring(0, i);
prefixs.add(prefix);
String suffix = targetStr.substring(length - i, length);
suffixs.add(suffix);
}
for(String prefix : prefixs){
for(String suffix : suffixs){
if(prefix.equals(suffix)){
postMatchs[length - 1] = prefix.length();
}
}
}
prefixs.clear();
suffixs.clear();
}
private void makeMatchs(){
for(int i = 7; 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());
}
}