KMP算法(java,c++)
java
public class KMP { public static int[] getNextArray(char[] t) { int[] next = new int[t.length]; next[0] = -1; next[1] = 0; int k; for (int j = 2; j < t.length; j++) { k=next[j-1]; while (k!=-1) { if (t[j - 1] == t[k]) { next[j] = k + 1; break; } else { k = next[k]; } next[j] = 0; //当k==-1而跳出循环时,next[j] = 0,否则next[j]会在break之前被赋值 } } return next; } public static int kmpMatch(String s, String t){ char[] s_arr = s.toCharArray(); char[] t_arr = t.toCharArray(); int[] next = getNextArray(t_arr); int i = 0, j = 0; while (i<s_arr.length && j<t_arr.length){ if(j == -1 || s_arr[i]==t_arr[j]){ i++; j++; } else j = next[j]; } if(j == t_arr.length) return i-j; else return -1; } public static void main(String[] args) { System.out.println(kmpMatch("abcabaabaabcacb", "abaabcac")); } }
c++
#include <iostream> #include <string> using namespace std; int next[8]; /*求单个回溯值 int GetNext(int j,char T[]) { if(j==0) return -1; if(j>0) { int k=GetNext(j-1,T); while (k>=0) if(T[j-1]==T[k]) return k+1; else k=GetNext(k,T); return 0; } return 0; }*/ void GetNext(char T[]) { int j=0,k=-1;next[j]=k; while (T[j]!='\0') if(k==-1 || T[j]==T[k]) {j=j+1;k=k+1;next[j]=k;} else k=next[k]; } int KMP(char S[],int start,char T[]) { int i=start,j=0; while (S[i]!='\0'&&T[j]!='\0') if(j==-1||S[i]==T[j]) {i=i+1;j=j+1;} else j=next[j]; if(T[j]=='\0') return(i-j); else return(-1); } int main() { //字符数组检测不到"\0" //char S[]={'d','f','g','a','b','a','a','b','c','a','c','f'}; //char T[]={'a','b','a','a','b','c','a','c'}; char S[]="gfylaa45e4daabaabcac"; char T[]="abaabcac"; GetNext(T); for(int i=0;i<8;i++) cout<<next[i]<<' '; cout<<endl; cout<<KMP(S,0,T)<<endl; return 0; }