假设需要使用KMP算法来寻找在某一段字符串中是否出现"ABCDABD"这个字符串,那么KMP算法最终要的一环就是计算该字符串的部分匹配值。
首先文字分析该字符串的部分匹配之的含义:
- 1,P[0]表示“A”,其完全前后缀都是空,所以其部分匹配值为0
- 2,P[1]表示“AB”,其完全前缀为{空,A},完全后缀为{B,空},前后缀中只有空相同,所以AB(即P[1])的匹配值为0
- 3,P[2]表示“ABC”,其完全前缀为{空,A,AB},完全后缀为{BC,B,空},前后缀中只有空相同,所以ABC(即P[2])的匹配值为0
- 4,P[3]表示“ABCD”,其完全前缀为{空,A,AB,ABC},完全后缀为{BCD,CD,D,空},前后缀中只有空相同,所以ABCD(即P[3])的匹配值为0
- 5,P[4]表示“ABCDA”,其完全前缀为{空,A,AB,ABC,ABCD},完全后缀为{BCDA,CDA,DA,A,空},前后缀中都有{A}长度为1,所以ABCDA(即P[4])的匹配值为1
- 6,P[5]表示“ABCDAB”其完全前缀为{空,A,AB,ABC,ABCD,ABCDA},完全后缀为{BCDAB,CDAB,DAB,AB,B,空},前后缀中都有{AB}长度为2,所以ABCDAB(即P[5])的匹配值为2
- 7,P[6]表示“ABCDABD”其完全前缀为{空,A,AB,ABC,ABCD,ABCDA,ABCDAB},完全后缀为{BCDABD,CDABD,DABD,ABD,BD,D,空},前后缀中只有空相同,所以ABCDABD(即P[6])的匹配值为0
import java.util.Scanner;
public class KMP_pipei {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while(scan.hasNext()){
String A = scan.nextLine();
//记录字符串的匹配值机对应的字符串
String jilu[][] = new String[A.length()][2];
for(int i = 0;i<A.length();i++){
String B = A.substring(0, i+1);
int changdu = chkRotation(B, B.length());
String sub = B.substring(0, changdu);
jilu[i][0] = B;
jilu[i][1] = String.valueOf(changdu);
System.out.printf("%s的匹配值为%s\n",jilu[i][0],jilu[i][1]);
}
}
}
//计算字符的匹配
public static int chkRotation(String A, int lena) {
String Abefore[] = new String[lena-1];
String Aafter[] = new String[lena-1];
int k=0;
int value = 0;
//计算部分匹配值,存放前缀
for(int i=0;i1;i--){
Aafter[lena-i] = A.substring(lena-i+1,lena);
}
//循环比较找出构建的数组中相同的字符段
while(k<lena-1){
if(Abefore[k].equals(Aafter[lena-k-2])){
value = Abefore[k].length();
}
k++;
}
return value;
}
}