public class kmp { /** * 主函数:返回 str2 在 str1 中第一次出现的位置 * @param str1 :母串 * @param str2 :标准串 * @return str2 在 str1 中第一次出现的位置 */ public static int getIndexOf(String str1, String str2){ if (str1==null||str2==null||str1.length()<1||str2.length()<1)return -1; char[] s1 = str1.toCharArray(); char[] s2 = str2.toCharArray(); int[] next = getNext(s2); int p1=0; //长数组的指针,纪录长数组的位置 int p2=0; //同上,短 while (p1<s1.length&&p2<s2.length){ if (s1[p1]==s2[p2]){ //如果相等,两个字符组同时向后移动 p1++; p2++; }else { if (next[p2]>0){ p2=next[p2]; }else { p1++; } } } //如果p2越界---》成功,p1是长的数组当前位置,p2是短的数组的长度,p1-p2是长的数组遇见短数组的初始位置 return p2==str2.length()?p1-p2:-1; } public static int[] getNext(char[] str2){ int[] next = new int[str2.length]; next[0]=-1; if (str2.length==1)return next; next[1]=0; /** * cn有两层含义: * 1.要和i-1处比较的字符的位置 * 2.i-1处的next值(next[i-1]==cn) */ int cn=0; int i=2; //这里cn和i也是对应的 while (i<next.length){ if (str2[i-1]==str2[cn]){//相等的话,在继承i-1处next值的基础上+1,同时cn。。。。 next[i++]=++cn; /** * cn=cn+1; cn+1的原因是:个人理解------ * 0到cn 共有cn+1个字符 与 i-1到i-1-cn 的字符相同 * * 其实,next数组存放的本来就是cn+1的位置,它本来在getIndexOf()中,就是要退到cn+1的位置的 * p2=next[p2]; * ******** ********* * cn cn+1 i-1 i * next[i++]=cn; */ }else { if (cn>0){ //往前跳,然后进行比较 cn=next[cn]; }else{ //没法跳了,当前next值为0 next[i++]=0; } } } return next; } }
04-17
2454
06-03
1012
11-03
3万+
04-09
545