【作者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. 关于蓝桥杯嵌入式STM32的一点收获

    各社团成员培训时自己总结的一点材料,直接粘过来的,可能有些朋友看不明白,总之这个比赛吧:有很多技巧,掌握到技巧能省我们半个月时间,我说的是针对这个比赛,对于STM32还是要多多练习,总之STM32还是 ...

  2. 开涛spring3(6.6) - AOP 之 6.6 通知参数

    前边章节已经介绍了声明通知,但如果想获取被被通知方法参数并传递给通知方法,该如何实现呢?接下来我们将介绍两种获取通知参数的方式. 使用JoinPoint获取:Spring AOP提供使用org.asp ...

  3. C# DataTable转换成实体列表 与 实体列表转换成DataTable

    /// <summary> /// DataTable转换成实体列表 /// </summary> /// <typeparam name="T"&g ...

  4. iOS安全攻防之使用 Frida 绕过越狱设备检测

    Frida 是 一款有趣的手机应用安全分析工具. 文章参考:Bypass Jailbreak Detection with Frida in iOS applications 在 Mac Termin ...

  5. React复习小结(一)

    一.React的发展 facebook在构建instagram网站的时候遇见两个问题: 1.数据绑定的时候,大量操作真实dom,性能成本太高 2.网站的数据流向太混乱,不好控制 于是facebook起 ...

  6. Heartbeat高可用解决方案

    Heartbeat高可用 Heartbeat作用: 通过heartbeat,可以将资源(ip以及程序服务等资源)从一台已经故障的计算机快速转移到另一台正常运转的机器上继续提供服务,一般称之为高可用服务 ...

  7. ubuntu16.04 英文环境安装中文输入法

    1. 安装语言包 System Settings–>Language Support–>Install/Remove Languages 选中chinese,点击Apply应用即可,等待下 ...

  8. ASP.NET Web API 自定义 HttpParameterBinding

    背景 问题的起因是这样的.群里面一个哥们儿发现在使用 ASP.NET WebAPI 时,不能在同一个方法签名中使用多次 FromBodyAttribute 这个 Attribute .正好我也在用 W ...

  9. 框架和css基础

    框架:一.框架集:1.<frameset></frameset>不能有<body>标签 属性:1)cols:把网页拆分成几列(左右拆分)eg:<framese ...

  10. 浅谈Android studio中OKHttp安装及简单使用

    Google貌似在6.0版本里面删除了HttpClient相关API,鉴于okhttp的口碑相当好,介绍一下OKHttp的安装及使用: 一.安装 对于Android Studio的用户,在Projec ...