最近看算法吧 看到一个题目 用到KMP算法 然后就找了些资料 最后发现一个 很不错的博客 这么好的东东 到现在才知道
http://www.matrix67.com/blog/archives/115 里面讲的东西很厉害 很牛叉! 就拿这个kmp算法来说 通俗易懂! 看了这篇文章的大致思想 自己整了个代码!
package com.sinitek.trading.program.client.interest;
/**
* Created with IntelliJ IDEA.
* User: xn-hyao-01
* Date: 13-11-4
* Time: 下午3:12
* To change this template use File | Settings | File Templates.
*/
public class KMP {
public static void main(String[] args) {
getIndex("abcdabcdabceabce");
kmp("abcdefghijk12k123fef", "k123");
}
public static void kmp(String source, String str) {
//获取 匹配下标
int[] points = getIndex(str);
//字符串长度
int sourceLength = source.length();
//str字符串长度
int strLength = str.length();
//i是source的索引 j是str的索引
int j = 0, i;
//循环进行匹配
for (i = 0; i < sourceLength && j < strLength; i++, j++) {
if (source.charAt(i) == str.charAt(j)) { //匹配则进行下一个匹配
} else {
//匹配失败 并且当前匹配的不是第2个 就是说已经至少有一个匹配成功了 所以可以找到最后一个匹配的覆盖下标 覆盖然后进行下轮匹配
if (j > 0) {
//因为还是当前字符比较 所以先减一 外面再加1就ok了
i--;
//让j指向最后一个匹配成功的 覆盖下标
j = points[j - 1];
} else {
//如果匹配失败 且是第一个 所以要重新匹配 把j=-1那么 下次就是重新匹配
j--;
}
}
}
//打印
System.out.print(j + " " + i);
}
/**
* 获取当前下标是最后一个匹配的成功的(下一个是匹配失败的 所以要往前挪,怎么挪呢 当然是覆盖原来的 比如已经匹配的是abcdabc 那么显然接下来 我们应该用abc去匹配后面的abc 而用d去进去尝试匹配刚才未匹配成功的那个)
*
* @param str
* @return 返回如果当前是最后一位匹配的时候 应该用什么跟当前的进行匹配没有的话返回-1 有的话返回跟当前匹配的下标 (取的是最大匹配)
*/
public static int[] getIndex(String str) {
//字符串长度
int length = str.length();
//返回 下次匹配的下标
int[] points = new int[length];
//如果最后一个匹配的下标是0 那么显然没有什么可以去覆盖第一个了 所以只能是-1(只要1个成功匹配 那么要覆盖也只能是自己覆盖自己 自己覆盖自己 还是第2个去匹配 显然不成功 所以是-1 )
points[0] = -1;
//第一个匹配是-1 所以可以直接初始化
int point = -1;
//进行遍历
for (int i = 1; i < length; i++) {
//默认是无法覆盖的
points[i] = -1;
//上一个的匹配是 point 那么如果当前跟point+1 匹配 则可以得到最大匹配是 point+1;
if (str.charAt(i) == str.charAt(point + 1)) {
//匹配 则将该下标的最大匹配设置为 前一个的匹配值加1
points[i] = point + 1;
//因为匹配成功了 所以下一个尝试的 前一个就是当前的了 所以point重置
point = point + 1;
} else {
/*如果匹配失败point=-1是说明跟第一个都没匹配 所以不可能再匹配了 直接是-1 如果不为-1则可以 进一步匹配 递归型的
abcdefgabcdefgabc
abcdefgabc
abc
*/
if (point > -1) {
//因为还是查找当前下标的匹配值 但是外面会加1 所以先减一
i--;
//重置point
point = points[point - 1];
}
}
}
//打印
for (int i : points) {
System.out.print(" " + i);
}
System.out.println();
return points;
}
}
看不懂的可以去看看推荐的那个博客! 讲的很清楚!