Java算法--字符串检索 KMP算法
彻底理解KMP:http://blog.csdn.net/v_july_v/article/details/7041827
KMP算法:http://blog.csdn.net/yutianzuijin/article/details/11954939
KMP求next和nextval:http://blog.sina.com.cn/s/blog_59b4a0b701015jtk.html
KMP算法讲解:http://www.cnblogs.com/c-cloud/p/3224788.html
KMP算法理解实现:http://kenby.iteye.com/blog/1025599
严蔚敏KMP:http://wenku.baidu.com/view/3ecafcd3a58da0116c1749eb.html
严版:
获取next数组:
//获取next数组 public static int[] GetNext(String str){ int j ,k; int next[] = new int[str.length()]; j=0;k=-1;next[0]=-1; while(j<str.length()-1){ if(k==-1||str.charAt(j)==str.charAt(k)){ j++;k++; next[j]=k; } else k=next[k]; } return next; }
改进:获取nextval数组
//获取nextval数组 public static int[] GetNextval(String str){ int j ,k; int nextval[] = new int[str.length()]; j=0;k=-1;nextval[0]=-1; while(j<str.length()-1){ if(k==-1||str.charAt(j)==str.charAt(k)){ j++;k++; if(str.charAt(j)!=str.charAt(k)){ nextval[j]=k; } else nextval[j]=nextval[k]; } else k=nextval[k]; } return nextval; }
搜索子串:
//搜索子串 public static int search(String mystr,String find){ int next[] = GetNext(find); int i = 0,j=0,v; while(i<mystr.length()&&j<find.length()){ if(j==-1||mystr.charAt(i)==find.charAt(j)){ i++;j++; } else j=next[j]; } if(j>=find.length()) v=i-find.length(); else v=-1; return v; }
main函数:
public static void main(String args[]){ String str1 ="ababbacbababcbce"; String find="ababc"; int[] next = GetNext(find); for(int i = 0 ; i <next.length ; i++){ System.out.print(next[i]+" "); } System.out.println("开始搜索..."); int i = search(str1,find); System.out.println(i); }
严版的next数组和nextval数组:
| 字符串 | a | b | a | b | b | a | c | b | a | b | a | b | c | b | c | e |
| next | -1 | 0 | 0 | 1 | 2 | 0 | 1 | 0 | 0 | 1 | 2 | 3 | 4 | 0 | 0 | 0 |
| nextval | -1 | 0 | -1 | 0 | 2 | -1 | 1 | 0 | -1 | 0 | -1 | 0 | 4 | 0 | 0 | 0 |
例如用abacb...和上面的字符串比较
如果是next数组比较到c!=b,那么,c还要和第一个b进行比较
如果是nextval数组,因为之前生成的时候已经考虑了str.charAt(1)==str.charAt(3),所以c不用再和第一个b进行比较,直接和最开始的a比较即可。
=================
另一个版本:
public class MyKmp { public static void main(String args[]){ String str1 ="ababcbacbababcbce"; String find="ababc"; int[] next = getNext(find); for(int i = 0 ; i <next.length ; i++){ System.out.print(next[i]+" "); } System.out.println(); search(str1,find,next); } //获取next数组 public static int[] getNext(String str){ int len = str.length(); int j = 0; int next[] = new int[len]; next[0]=next[1]=0; for(int i = 1 ;i<len-1 ; i++){ while(j>0&&str.charAt(i)!=str.charAt(j)) j=next[j]; if(str .charAt(i)==str.charAt(j)){ j++; } next[i+1]=j; } return next; } //搜索子串 public static void search(String original,String find, int next[]){ int j = 0; for(int i = 0 ; i < original.length() ;i ++){ while(j>0 && original.charAt(i)!=find.charAt(j)) j=next[j]; if(original.charAt(i)==find.charAt(j)){ if(j==find.length()-1){ System.out.println("找到字符串,位置在"+(i-j)); System.out.println(original.subSequence(i - j , i + 1)); System.out.println(j); //return; j=next[j]; } else j++; } } } }

浙公网安备 33010602011771号