/********查找匹配字符串**********/ //最原始、复杂度最高的做法 //返回childstr在mumstr中第pos个字符之后的位置,如果不存在,则返回0 public int FindStr(String mumstr, String childstr, int pos) { //省去参数有效性判断 if((childstr.length() > mumstr.length()) || (pos >= mumstr.length())) return 0; char[] mumarr = mumstr.toCharArray(); char[] childarr = childstr.toCharArray(); int i = pos; int j = 0; while((i < mumarr.length) && ( j < childarr.length)) { //如果匹配情况 if( mumarr[i] == childarr[j]) { ++i; ++j; } //如果不匹配,则从头开始匹配 else { i = i - j + 1; j = 0; } } //判断是否匹配成功,如果匹配成功,则跳出循环条件应该为 j = childarr.length情况 if( j >= childarr.length) { return i - j; } return 0; } /**************KMP算法*****************/ //KMP算法主要思想在于比较指针不回溯,通过计算next[j],将匹配指针回溯到next[j]位置与i位置的主字符串进行比较 //next[j]计算函数 /*初始化next[1] = 0;(注意实现时要注意算法中str的位置与算法中位置的区别) 且注意计算next[j]时,比较的是一直到j-1的字符串 next[j]计算共分为两种情况:记next[j] = k; 1.str[j] = str[k],则next[j + 1] = next[j] + 1 = k + 1; 2.若不等,则把比较想象成模式和主字符串都是childstr的模式匹配。则应该让str[j] 和str[next[k]]进行比较(这里记next[j] = k); 1) 相等,则next[j + 1] = next[k] + 1 = k' + 1; 2) 不相等,则继续令next[k] = k',将str[j]与str[k' + 1]作比较; */ private int[] getNext(String childstr) { //参数初始化 int length = childstr.length(); char[] childarr = childstr.toCharArray(); int next[] = new int[length]; next[0] = -1;//标志位字符串初始位 int i = 0; int j = -1; while ( i < length - 1) { if( i == 0 || j == -1 ||childarr[i] == childarr[j])//注意不能忘记j=-1的初始情况 { next[++i] = ++j; } else { j = next[j]; } } return next; } /*******************KMP算法********************/ public int IndexKMP(String mumstr, String childstr, int pos) { if((childstr.length() > mumstr.length()) || (pos >= mumstr.length())) return 0; char[] mumarr = mumstr.toCharArray(); char[] childarr = childstr.toCharArray(); int i = pos; int j = 0; int[] next = getNext(childstr); while ((i < mumarr.length)&&(j < childarr.length)) { if(j == -1 || mumarr[i] == childarr[j])//注意还要加上j=-1的最初始化情况 { ++i; ++j; } else { //i不变,j变为next[j] j = next[j]; } } if ( j >= childarr.length) { return i - j; } return 0; } public static void main(String[] args) { StrMatch strMatch = new StrMatch(); String aString = "ababccddefgabcdefghij"; String bString = "ababccddefg"; System.out.println(strMatch.IndexKMP(aString, bString, 3)); } /********改进的nextval算法********/ /*当遇到 a a a a b 情况 next[j] 0 1 2 3 4 nextval[j]0 0 0 0 1 即当比较到b时不等,回溯到next[4] = 3位置,比较a,仍不等则继续前移next[3] = 2;仍然是比较a,结果仍然是不等 故希望能够直接回溯至第一个a位置; 则改进算法中,next[j] = k; 若str[j] = str[k],则应和str[next[k]]进行比较,若str[j] = str[next[k]],则继续前移, 直至str[j]与其不相等;则next[j] = next[k],直至不相等的初始情况 */ private int[] nextval(String childstr) { //参数初始化 int length = childstr.length(); char[] childarr = childstr.toCharArray(); int next[] = new int[length]; next[0] = -1;//标志位字符串初始位 int i = 0; int j = -1; while ( i < length - 1) { if( i == 0 || j == -1 ||childarr[i] == childarr[j])//注意不能忘记j=-1的初始情况 { ++i; ++j; //再多一层对相等元素的判断 if(childarr[i] == childarr[j])//对应next[j] = next[k]情况 { next[i] = next[j]; } else { next[i] = j; } } else { j = next[j]; } } return next; }
原文:http://blog.csdn.net/woliuyunyicai/article/details/44622573