KMP算法 学习笔记

kmp算法在很多人看来是如此的厉害,很早之前就学过了,但是各种看不懂把我拦住了,现在重新拾取,来写一下个人的学习总结。

kmp看毛片算法(小甲鱼教的)(在这给小甲鱼做个广告,我个人看来小甲鱼讲的数据结构很好,很有趣。个人创业不容易,希望大家多多支持www.fishc.com小甲鱼,我跟小甲鱼素不相识,只是有用的东西大家分享)

好了言归正传。

如果你之前看过kmp算法没有看懂希望在这不要带着一种恐惧感,如果你没看过那是更好。

网上有很多详细教程,但是大部分都很啰嗦,容易把人看晕。

kmp算法没有什么难的,你只要记住一点:kmp算法就是提前处理一下我们要找的字符串。

我们怎样来处理要找的字符串呢?

举个例子就是....例子好复杂。

我直接说视频吧。我想没有很么能比视频讲的明白了 。

视频的下载地址在这里

http :

//pan.baidu.com/s/1eQtceWE

好了,继续说,视频上讲的简单明了。很适合我们的思维。

在这里补充一点就是,在视频中小甲鱼的

else
		{
			j=next[j];
		}

没有讲明白,我给大家补充一下我的想法。(当大家看了视频就会知道是哪里了)。

就是当s[i]!=s[j]的时候要将j返回到next[j]所指的位置,大家可以这样来想,我们的next的数组是干嘛的,不就是为了不匹配的时候我们向前来跳转的嘛,这里就直接用上就行了。可能我说的也有一点模糊,但是大家想一下,现在把前面这个字符串当做是要找的字符串,后面这个是那个s串(也就是长的串(这样说不太好,但是容易理解)),这样我们找不到,自然就要回到next【j】了。对吧。

好了下面贴上看完视频后自己还原的代码:

#include<iostream>
#include<string>
using namespace std;
//kmp算法
//next数组的构建
void get_next(string s,int * next)
{
	int i=0;
	int j=-1;
	next[0]=-1;
	while(i<s.size())
	{
		if(j==-1||s[i]==s[j])
		{
			i++;
			j++;
			next[i]=j;
		}
		else
		{
			j=next[j];
		}
	}
}
int main()
{
	string s,t;
	cin>>s>>t;
	int next[1000];
	get_next(t,next);
	//下面是kmp算法的实现 我是从开头开始查询的 返回了位置。
	int i=0,j=0;
	int ssize=s.size();
	int tsize=t.size();
	while(i<ssize&&j<tsize)
	{
		if(j==-1||s[i]==t[j])
		{
			i++;
			j++;
		}
		else
		{
			j=next[j];
		}
	}
	if(j==t.size())
	{
		cout<<i-tsize+1<<endl;
	}
	else
	{
		cout<<"no"<<endl;
	}
	system("pause");
}

其中存在视频中所说的优化问题下面来进行优化:

#include<iostream>
#include<string>
using namespace std;
//kmp算法
//next数组的构建
void get_next(string s,int * next)
{
	int i=0;
	int j=-1;
	next[0]=-1;
	while(i<s.size())
	{
		if(j==-1||s[i]==s[j])
		{
			i++;
			j++;
			if(s[i]==s[j])
				next[i]=next[j];
			else
				next[i]=j;
		}
		else
		{
			j=next[j];
		}
	}
}
int main()
{
	string s,t;
	cin>>s>>t;
	int next[1000];
	get_next(t,next);
	//下面是kmp算法的实现 我是从开头开始查询的 返回了位置。
	int i=0,j=0;
	int ssize=s.size();
	int tsize=t.size();
	while(i<ssize&&j<tsize)
	{
		if(j==-1||s[i]==t[j])
		{
			i++;
			j++;
		}
		else
		{
			j=next[j];
		}
	}
	if(j==t.size())
	{
		cout<<i-tsize+1<<endl;
	}
	else
	{
		cout<<"no"<<endl;
	}
	system("pause");
}

好了!

感谢自己坚持。

KMP算法 学习笔记

时间: 2024-10-07 03:12:19

KMP算法 学习笔记的相关文章

KMP算法学习笔记

http://www.matrix67.com/blog/archives/115 Orz maxtix67 一直拖着到碰到了KMP算法的题才学.. 设有字符串A:abefgababef 模式串 B:abefgabef 当A与B进行匹配时,设i是A上的指针,j是B上的指针,则A和B匹配到第8位就会失配.按照常规方法,我们会将i跳回到2,j跳回到1进行匹配.观察之后我们会发现其实这是多余的,因为中间的befg都是不可能的,我们应该直接跳到A的第6位进行匹配. KMP算法就是通过过滤这样无用字符来加

字符串匹配-KMP算法学习笔记

参考文章: 1.字符串匹配的KMP算法 2.KMP算法详解 3.从头到尾彻底理解KMP 版权声明:本文为博主原创文章,未经博主允许不得转载.

算法学习笔记 KMP算法之 next 数组详解

最近回顾了下字符串匹配 KMP 算法,相对于朴素匹配算法,KMP算法核心改进就在于:待匹配串指针 i 不发生回溯,模式串指针 j 跳转到 next[j],即变为了 j = next[j]. 由此时间复杂度由朴素匹配的 O(m*n) 降到了 O(m+n), 其中模式串长度 m, 待匹配文本串长 n. 其中,比较难理解的地方就是 next 数组的求法.next 数组的含义:代表当前字符之前的字符串中,有多大长度的相同前缀后缀,也可看作有限状态自动机的状态,而且从自动机的角度反而更容易推导一些. "前

算法学习笔记 递归之 快速幂、斐波那契矩阵加速

递归的定义 原文地址为:http://blog.csdn.net/thisinnocence 递归和迭代是编程中最为常用的基本技巧,而且递归常常比迭代更为简洁和强大.它的定义就是:直接或间接调用自身.经典问题有:幂运算.阶乘.组合数.斐波那契数列.汉诺塔等.其算法思想: 原问题可分解子问题(必要条件): 原与分解后的子问题相似(递归方程): 分解次数有限(子问题有穷): 最终问题可直接解决(递归边界): 对于递归的应用与优化,直接递归时要预估时空复杂度,以免出现用时过长或者栈溢出.优化递归就是以

EM算法学习笔记2:深入理解

文章<EM算法学习笔记1:简介>中介绍了EM算法的主要思路和流程,我们知道EM算法通过迭代的方法,最后得到最大似然问题的一个局部最优解.本文介绍标准EM算法背后的原理. 我们有样本集X,隐变量Z,模型参数θ,注意他们3个都是向量,要求解的log似然函数是lnp(X|θ),而这个log似然函数难以求解,我们假设隐变量Z已知,发现lnp(X,Z|θ) 的最大似然容易求解. 有一天,人们发现引入任意一个关于隐变量的分布q(Z),对于这个log似然函数,存在这样一个分解: lnp(X|θ)=L(q,θ

算法学习笔记 最短路

图论中一个经典问题就是求最短路,最为基础和最为经典的算法莫过于 Dijkstra 和 Floyd 算法,一个是贪心算法,一个是动态规划,这也是算法中的两大经典代表.用一个简单图在纸上一步一步演算,也是很好理解的,理解透自己多默写几次即可记住,机试时主要的工作往往就是快速构造邻接矩阵了. 对于平时的练习,一个很厉害的 ACMer  @BenLin_BLY 说:"刷水题可以加快我们编程的速度,做经典则可以让我们触类旁通,初期如果遇见很多编不出,不妨就写伪代码,理思路,在纸上进行整体分析和一步步的演算

[算法学习笔记]直接插入排序笔记

直接插入排序概念: 带排元素放在elem[0...n-1]中,初始化时,elem[0]自成1个有序区,无序区为elem[1...n-1],从i=1起,到i=n-1,依次将elem[i]插入有序区[0...n-1]中 直接插入排序算法步骤: 1.在当前有序区域R[1,i-1]中查找R[i]的正确插入位置K(1<=K<=i-1) 2.将R[K,i-1]中的记录均向后移动 3.移动后腾出K位置,插入R[i] (最坏)时间复杂度:O(n^2) 空间复杂度:O(1) /// <summary>

八大排序算法学习笔记:冒泡排序

冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)是一种简单的排序算法. 它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成.这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端. 算法原理: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数. 针对所有

由LCS到编辑距离—动态规划入门—算法学习笔记

一切计算机问题,解决方法可以归结为两类:分治和封装.分治是减层,封装是加层. 动态规划问题同样可以用这种思路,分治. 它可以划分为多个子问题解决,那这样是不是用简单的递归就完成了?也许是的,但是这样会涉及太多的不便的操作.因为子问题有重叠! 针对这种子问题有重叠的情况的解决,就是提高效率的关键. 所以动态规划问题可以总结为:最优子结构和重叠子问题. 解决这个子问题的方式的关键就是:memoization,备忘录. 动态规划算法分以下4个步骤: 描述最优解的结构 递归定义最优解的值 按自底向上的方