KMP算法
来源:互联网 发布:剑网三大师捏脸数据 编辑:程序博客网 时间:2024/06/05 18:01
最近看算法吧 看到一个题目 用到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; }}
看不懂的可以去看看推荐的那个博客! 讲的很清楚!
- KMP算法详解 【KMP】
- 【KMP】KMP算法模板
- KMP hihoCoder1015 KMP算法
- kmp算法
- KMP算法
- KMP算法
- KMP算法
- KMP算法
- KMP 算法
- kmp算法
- KMP算法
- kmp算法
- KMP算法
- KMP算法
- kmp算法
- kmp算法
- KMP算法
- KMP算法
- 关于C++虚函数
- java平台统一异常框架的设计与实现 .
- Android开发者指南-Manifest.xml-<supports-screens>[原创译文]
- C++类与对象的进一步讨论(1)
- NP完全问题
- KMP算法
- mysql innodb redo log
- 任职23年 苹果iOS工程副总裁Henri Lamuraux退休
- [剑指Offer]3.矩形覆盖
- ACEGI配置总结
- 在Windows下编译Mapnik的依赖库
- C++类与对象的进一步讨论(2)
- MySQL 修改mysqlroot密码
- MongoDB之DBref(关联插入,查询,删除) 实例深入