【作者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. 由12306.cn谈谈网站性能技术

    12306.cn网站挂了,被全国人民骂了.我这两天也在思考这个事,我想以这个事来粗略地和大家讨论一下网站性能的问题.因为仓促,而且完全基于本人有 限的经验和了解,所以,如果有什么问题还请大家一起讨论和 ...

  2. 数据库插入数据失败,log提示不能将值 NULL 插入列 'id'

    已经记不住具体的log信息了,意思就是ID如果没有设置为自增长的情况下就不能插入数据,而建表时ID字段是设置为"not null",所以就不能顺利插入数据. 解决方法有两种: ①建 ...

  3. 《物联网框架ServerSuperIO教程》-19.设备驱动和OPC Client支持mysql、oracle、sqlite、sqlserver的持久化。v3.6.4版本发布

    19.设备驱动和OPC Client支持mysql.oracle.sqlite.sqlserver的持久化 19.1     概述 ServerSuperIO支持设备驱动和OPC Client采集的数 ...

  4. 让Chrome看不了WWDC直播的HLS技术详解

    Requirements: Live streaming uses Apple's HTTP Live Streaming (HLS) technology. HLS requires an iPho ...

  5. BOM(2)

    Window 子对象 (1)Location 对象 Location 对象包含有关当前 URL(统一资源定位符) 的信息.(Uniform Resource Location) Location 对象 ...

  6. iOS bug调试技巧学习----breakpoint&condition

    给断点添加条件 - (void)testCondition2 { NSArray *array = @[@"我们", @"一起", @"来" ...

  7. hibernate操作步骤(代码部分)

    1.加载hibernate的核心配置文件 2.创建SessionFactory对象 3.使用SessionFactory创建Session对象 4.开启事务(手动开启) 5.写具体逻辑crud,增删改 ...

  8. angularJS loading 载入画面

    在请求网络的时候,显示loading画面 1. 使用http的interceptor,截断处理所有的http请求和响应,以及错误.在request的时候设置$rootScope.loading=Tru ...

  9. python 标准库 -- requests

    一. 安装 $ pip install requests requests 并不是python 标准库, 但为了汇总方便, 将其放置于此. 二. 用法 requests.get() : GET 请求 ...

  10. Vue按需加载提升用户体验

    Vue官方文档异步组件: 在大型应用中,我们可能需要将应用拆分为多个小模块,按需从服务器下载.为了让事情更简单, Vue.js 允许将组件定义为一个工厂函数,动态地解析组件的定义.Vue.js 只在组 ...