Kmp算法习题演练
KMP算法是一种改进的字符串匹配算法,核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。
例题: 在字符串str1中匹配str2
str1=“abbbcchabbbccikkkabciabckkk”
str2=“abciabc”
主函数类:
package Supplement;
import java.util.List;
import java.util.Stack;
public class Main {
public static void main(String[] agrs){
/**
* kmp算法
* 匹配字符串str1中是否含有字符串str2
* */
Practice practice = new Practice();
String str1 = "abbbcchabbbccikkkabciabckkk";
String str2 = "abciabc";
int index = practice.getIndexOf(str1,str2);
System.out.println("开始匹配的位置是:"+ index);
}
}
实现类:
package Supplement;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;
public class Practice {
/**
* kmp算法
* 求字符串str1 中是否包含字符串str2
* ***/
//kmp算法
public int getIndexOf(String str1,String str2){
if(str1 == null || str2 == null || str1.length() <1 || str2.length() < 1) return -1;
char[] arr1 = str1.toCharArray();
char[] arr2 = str2.toCharArray();
int index1 = 0; //数组1匹配的位置
int index2 = 0; //数组2匹配的位置
int[] str2Next = getNextArray(arr2); //数组2的重复部分的小标
while (index1 < arr1.length && index2 < arr2.length){
if(arr1[index1] == arr2[index2]) { //匹配成功
index1++;
index2++;
}else if(str2Next[index2] == -1){
index1++; //arr2已经回溯到开头依旧无法匹配上,arr1放弃已经匹配成功匹配的部分,从后面重新开始
}
else index2 = str2Next[index2]; //回溯之前匹配成功的部分,将arr1已经匹配成功的部分舍弃
}
return index2==arr2.length?index1-index2:-1; //匹配成功,则index1-index2的结果就是开始匹配的位置。否则返回-1匹配失败
}
//求str2局部匹配信息
public int[] getNextArray(char[] arr2){
if(arr2.length == 0) return new int[]{-1}; //0位置设置为-1;
int [] next = new int[arr2.length];
next[0] = -1; //0位置人为设置为-1;
next[1] = 0; //1位置认为设置为0;
int i = 2;
int cn = 0;
while (i 0) cn = next[cn]; //没匹配上,cn往前跳
else next[i++] = 0; //全没有匹配上,该节点为0
}
return next;
}
}
主方法 getIndexOf() 部分代码图解: