【作者Idlear  博客:http://blog.csdn.net/idlear/article/details/19555905】
           这估计是算法连载文章的最后几篇了,马上就要开学了,以后关于算法的更新肯定没有之前那么快了,一方面是因为算法这几篇作为入门也已经算是可以了,我常记得我以前老师说的一句话就是万事开头难,学习计算机就像武侠小说里面练武功一样,一旦打开任督二脉,练成绝世武功就是时间的问题了,另外也是因为我自己的原因也该将精力转向其他的知识了,我的脑子装的还是最原始的系统只能运行一个线程,如果我不手动的去给他切换一下,估计我就要挂在这一棵树上了。接下来任务还是挺繁重的,我想将关于我博客分类里的几个技术的知识都去整理一下,对于之前的设计模式的文章我实在是对不住了,现在看看写的那些感觉就跟翔一样,我会抽时间再重新返厂加工的,对于博客我还是新手,虽然写的并不多,但是却渐渐的喜欢上写博客。也同时谢谢大家的支持,让我们一起加油一起进步吧。
           言归正传字,符串匹配算法就是看字符串a中是否包含字符串b或者a与b是否相等,可能大家最先想到的比较就是for循环嵌套直接一个个的对比即可,这是最普通的匹配算法,也是比较暴力的方式他的学名叫做BF算法,我们这里要说的是KMP算法,KMP算法之所以叫做KMP算法是三个人名字的首字母,他们三个人发现了KMP算法。这里我们定义一下字符串匹配中主串是模板,而子串则是用来验证主串中是否存在的样本。在BF算法中我们可以简单的想象一下,主串跟子串上各有一个指针,比较的过程就是两个指针不停的前进后退。但是要是让我们去看简单的字符串匹配的的问题时,我们根本不需要这样每一次都前进回退的比较,因为有很多值可以很明显的看出来不需要回退,所以如何让算法更加的聪明呢,这里KMP算法就让时间复杂度降到了O(m+n)主串的指针不需要回退,只有子串的指针回退,而子串的指针也不是简单的回到最前面。而是根据一个规则。这里我们需要去好好的研究一下字符串的特点。
我们首先看这样两个字符串 ABADEFG    跟ABD     首先是A与A相比相同,我们去比较B与B相比相同,然后A与D相比不同,这里是不是我们需要退回到B与A相比的位置呢?我们BF算法是这样的,但是我们可以想一下,主串的AB与子串的AB都相同,而这时候我们再去回退去比较主串的B与A是否相等是不是没有必要了,这时候我们应该直接去比较主串的A与子串的A也就是主串的第第三个位置与主串第一个位置,这样主串并没有后退,这是怎么做到的呢,其实我们可以一直分析子串,我们可以想一下如果主串的的每一个都跟子串的第一位不相同那么是不是主串不需要回退就可以完成循环,结果也肯定是没有匹配成功,那么如果主串前n位与子串的前k位相同,那么说明主串的前n-1位与子串的k-1位相同那么我们是不是相当于复制了主串的n-1位,我们可以直接利用子串来处理就知道子串的第k位与主串的第前n-1位是否相等,而更重要的是我们可以得到一个数组,这个数组就是规定我们子串指定的回退位置。其实只要有了这个意识学习kmp就简单多了。而kmp算法的核心就是处理子串计算出回退数组。

          这个例子很好的解释了子串回退数组的生成。大家可以根据他写出算法。可能有很多人觉得kmp算法比较难懂,其实的确是这样的,模式匹配算法中还有很多简单效率可能要比kmp算法还要好的算法,有兴趣的朋友可以查一下像sunday算法,indexof的算法(这个算法就是javaString的indexof方法的实现的算法,测试一下比KMP算法要快了)但是不得不承认KMP算法已成为经典通用的字符串匹配算法。
public class KMP {
	public int kmp(char[] s, char[] ss) {
		int[] next = core(ss);
		int i = 0;
		int j = 0;
		while (i < s.length && j < ss.length) {
			if (j == -1 || s[i] == ss[j]) {
				i++;
				j++;
			} else {
				j = next[j];
			}
		}
		if (j >= ss.length) {
			return i - ss.length+1;
		}
		return -1;
	}

	public int[] core(char[] ss) {

		int i = 0;
		int[] next = new int[ss.length];
		next[0] = -1;
		int j = -1;
		while (i < ss.length-1) {
			if (j == -1 || ss[i] == ss[j]) {
				++i;
				++j;
				if (ss[i] != ss[j]) {
					next[i] = j;
				} else {
					next[i] = next[j];
				}
			} else {
				j = next[j];
			}
		}

		return next;
	}
	public static void main(String[] args) {
		KMP kmp=new KMP();
		System.err.println(kmp.kmp("asdfsasf".toCharArray(), "sasf".toCharArray()));
	}
}

算法起步之kmp算法的更多相关文章

  1. 算法起步之Kruskal算法

    原文:算法起步之Kruskal算法 说完并查集我们接着再来看这个算法,趁热打铁嘛.什么是最小生成树呢,很形象的一个形容就是铺自来水管道,一个村庄有很多的农舍,其实这个村庄我们可以看成一个图,而农舍就是 ...

  2. 算法起步之Prim算法

    原文:算法起步之Prim算法 prim算法是另一种最小生成树算法.他的安全边选择策略跟kruskal略微不同,这点我们可以通过一张图先来了解一下. prim算法的安全边是从与当前生成树相连接的边中选择 ...

  3. 算法起步之Bellman-Ford算法

    原文:算法起步之Bellman-Ford算法 从这篇开始我们开始介绍单源最短路径算法,他是图算法之一,我们前面说的贪心,图的遍历,动态规划都是他的基础,单源最短路径其实说的就是图中节点到节点的最短路径 ...

  4. 算法起步之Dijkstra算法

    原文:算法起步之Dijkstra算法 友情提示:转载请注明出处[作者 idlear    博客:http://blog.csdn.net/idlear/article/details/19687579 ...

  5. 算法笔记之KMP算法

    本文是<算法笔记>KMP算法章节的阅读笔记,文中主要内容来源于<算法笔记>.本文主要介绍了next数组.KMP算法及其应用以及对KMP算法的优化. KMP算法主要用于解决字符串 ...

  6. 问题 1690: 算法4-7:KMP算法中的模式串移动数组

    题目链接:https://www.dotcpp.com/oj/problem1690.html 题目描述 字符串的子串定位称为模式匹配,模式匹配可以有多种方法.简单的算法可以使用两重嵌套循环,时间复杂 ...

  7. 字符串匹配(BF算法和KMP算法及改进KMP算法)

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include<cstring> ...

  8. 算法总结篇---KMP算法

    目录 写在前面 例题 剪花布条 Radio Transmission OKR-Periods of Words 似乎在梦中见过的样子 Censoring 写在前面 仅为自用,不做推广 一起来看猫片吧! ...

  9. 经典KMP算法C++与Java实现代码

    前言: KMP算法是一种字符串匹配算法,由Knuth,Morris和Pratt同时发现(简称KMP算法).KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的.比 ...

随机推荐

  1. 《Android进阶》之第六篇 Fragment 的使用2

    最近通过学习,对fragment的使用有了新的认识. 一开始接触android的时候,很是受不了这个fragment,总感觉它把一个简单的事情搞复杂啦,所以每次新建工程的时候总是固执的选择empty ...

  2. AsyncTask和Handler

    AsyncTask实现的原理和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口 ...

  3. aws上redhat安装redis服务记

    1.准备 官网下载

  4. java中文件操作《一》

    在日常的开发中我们经常会碰到对文件的操作,在java中对文件的操作都在java.io包下,这个包下的类有File.inputStream.outputStream.FileInputStream.Fi ...

  5. 《HelloGitHub》第 14 期

    公告 欢迎通过在 GitHub 上新建 issues 方式推荐项目,我真心希望读者可以在 HelloGItHub,找到真正的编程乐趣! <HelloGitHub>第 14 期 兴趣是最好的 ...

  6. C语言之循环结构

    程序结构: 顺序结构 条件结构(分支结构) if结构,if-else结构 ,多重if分支结构,switch结构 循环结构:做重复的事情 while循环,do..while循环和for循环. 写循环结构 ...

  7. 修改tomcat图标

    页面上加入: 1 <link rel="shortcut icon" href="favicon.ico" type="image/x-icon ...

  8. javaSE_08Java中static、继承、重写

    一.Static 学习静态这个关键字,关键是抓住两个点: 1,关注其语法特点 2,关注其使用场景 案例讲解: 我们先从静态变量开始,当一个成员变量加上static修饰之后,会是一个什么效果? 比如创建 ...

  9. unity3D:游戏分解之角色移动和相机跟随

          游戏中,我们经常会有这样的操作,点击场景中某个位置,角色自动移动到那个位置,同时角色一直是朝向那个位置移动的,而且相机也会一直跟着角色移动.有些游戏,鼠标滑动屏幕,相机就会围绕角色旋转. ...

  10. nginx反向代理cas server之1:多个cas server负载均衡配置以及ssl配置

    系统环境采用centOS7 由于cas server不支持session持久化方式的共享,所以请用其他方式代替,例如:组播复制. 为什么不支持session持久化:http://blog.csdn.n ...