1 原理
参考 《大话数据结构》第5章 串 的第5.7小节 : KMP模式匹配算法
2 java代码
KMP.java
package leaning.string.KMP; public class KMP { public static int indexKMP(String source, String target,int pos) { /* i 用于主串source当前位置下标值,若pos不为1 则从pos位置开始匹配 */ int i = pos ; /* j 用于子串 target中当前位置下标值 */ int j = 1 ; /*定义一组next数组*/ int[] next = new int[IntArrayLength.length]; /*对target进行分析,得到next数组*/ next = NextUtil.getNext(target); // 将source,target字符串变为字符数组 char[] sourceChar = KMPStringUtil.stringToChar(source); char[] targetChar = KMPStringUtil.stringToChar(target); //若i小于source长度并且target小于target长度,执行循环 while(i <=source.length() && j <= target.length() ){ if(j==0 || sourceChar[i] == targetChar[j] ){ ++i; ++j; }else{ j = next[j] ; } } if( j > target.length() ){ return i - target.length(); }else{ return 0; } } public static void main(String args[]) { String source = "asdkfjslkfjwejdklfjew8odklfjsdlkfjslkdj"; String target = "w8odkl"; int pos = 0; int p = KMP.indexKMP(source, target, pos); System.out.println("在位置 " +p + "完全匹配"); } }
package leaning.string.KMP; public class NextUtil { /** * * 得到next数组 * */ public static int[] getNext( String targetStr) { if(targetStr==null) return null; char[] targetModify = KMPStringUtil.stringToChar(targetStr); // 将targetStr字符串改为字符数组 int length = targetStr.length(); // 得到next数组 int i,j; i = 1 ; j = 0 ; int next[] = new int[IntArrayLength.length]; while( i < length){ if(j == 0 || targetModify[i] == targetModify[j]){ // targetModify[i]表示后缀单个字符, targetModify[j]表示前缀的单个字符 ++i; ++j; next[i] = j ; }else{ j = next[j]; // 若字符不同,则 j 进行回溯 } } return next; } public static void main(String args[]){ String targetStr = "ababaaaba" ; int next[] = NextUtil.getNext(targetStr); for(int i = 0 ; i < next.length ; i++){ System.out.print(next[i] + " "); } } }
IntArrayLength.java
package leaning.string.KMP; public class IntArrayLength { public static int length = 255; }
package leaning.string.KMP; public class KMPStringUtil { public static char[] stringToChar(String source){ /** * 对source进行改造,使其第一位为一个占位符 * source = a b c d e f g h * targetModify = '' a b c d e f g h * * */ char[] targetModify = new char[source.length()+1]; int length = source.length() ; for(int i = 0 ; i < source.length() ; i++){ targetModify[i+1] = source.charAt(i); } return targetModify; } }
运行 KMP.java 得到下面结果