2025-01-25 KMP算法-查找字符串问题
This commit is contained in:
parent
3b53efd9a0
commit
d11a8f629c
124
src/dataANDcalc/java/algorithm/KMP.java
Normal file
124
src/dataANDcalc/java/algorithm/KMP.java
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user