【初识】KMP算法入门(转)
感觉写的很好,尤其是底下的公式,易懂,链接:http://www.cnblogs.com/mypride/p/4950245.html
举个例子
模式串S:a s d a s d a s d f a s d
匹配串T:a s d a s d f
如果使用朴素匹配算法——
1 2 3 4 5 6 7 8 9
a s d a s d a s d f a s d
a s d a s d f
1 2 3 4 5 6
此时,匹配到了S7和T7了,S7为a而T7为f,不匹配那么朴素的匹配算法会这么做——
1 2 3 4 5 6 7 8 9
a s d a s d a s d f a s d
a s d a s d f
1 2 3 4 5 6 7
这时,我们会发现,模式串回溯到了S2,而匹配串回溯到了T1。
很明显,这会极大的降低算法的效率,在最坏情况下,我们需要将模式串几乎每个元素都查询一次,而每次查询都从匹配串的串首走到接近串尾,这样的时间复杂度为n*m,其中n和m分别为模式串和匹配串的长度。
那么我们是否有可能降低时间复杂度呢?答案是肯定的——很明显我们只需要想办法减少回溯,就可以达到效果。Kmp算法就是使用这种方法节省时间的。
1 2 3 4 5 6 7 8 9
a s d a s d a s d f a s d
a s d a s d f
1 2 3 4 5 6 7
这个东西很熟悉吧?刚刚出现过一次。
那么,kmp算法会怎么执行下一步呢?答案如下——
1 2 3 4 5 6 7 8 9
a s d a s d a s d f a s d
a s d a s d f
1 2 3 4 5 6 7
注意这一步!这里的模式串根本没有回溯,只是将匹配串向后移动了若干步。这样,最坏情况只是将模式串走一遍,然后将匹配串走一遍,当然了,匹配串里 面的部分元素会走多次,但是,很明显这种算法会将n*m降低到n+k,这个k和m内部部分元素的重复次数有关,最大不会超过n(当然这是我自己证明得到 的,不一定正确,以后我还会继续证明的)。
好了,方法知道了,那么怎么实现呢?
换句话说,怎么实现迅速的移动匹配串呢?答案是——添加一个Next数组,标记匹配串中的特性。
这个Next数组的特性很明显
- Next[0] = -1,即这是第一个元素,前面没有可以替换它的。
- Next[j] = k ; { k | T[0] = T[j-k], T[1] = T[j-k+1],... , T[k-1] = T[j-1]}。
- Next[j] = 0; 其他情况。
举例:
匹配串T: a s d a s d f
Next: -1 0 0 0 1 2 3
具体见代码——
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
;
char s[N], t[N];
int Next[N];
int lenS, lenT;
void kmpNext(char* T) //计算Next数组
{
;
Next[] = -; //Next[0] = -1
while(i < lenT)
{
;
while(T[j] == T[i]) //Next[i] = j; { j | T[0] = T[i-j], T[1] = T[i-j+1],... , T[j-1] = T[i-1]}
{
Next[i] = j;
i++;
j++;
}
Next[i] = j; //同上,或等于0
i++;
}
}
bool kmp(char* S, char* T) //kmp
{
lenS = strlen(S);
lenT = strlen(T);
kmpNext(T);
, j = ;
while(i < lenS && j < lenT) //当模式串或匹配串走完时退出
{
)
{
i++;
j = ;
}
else if(S[i] == T[j])
{
i++;
j++;
}
else j = Next[j];
}
; //如果匹配串走完,表示匹配串是模式串的子串
;
}
int main()
{
//freopen("test.in", "r", stdin);
while(~scanf("%s%s", s, t))
{
if(kmp(s, t)) printf("Yes\n");
else printf("No\n");
}
;
}
【初识】KMP算法入门(转)的更多相关文章
- 【初识】KMP算法入门
举个例子 模式串S:a s d a s d a s d f a s d 匹配串T:a s d a s d f 如果使用朴素匹配算法—— 1 2 3 4 5 6 8 9 a s d a s d a s ...
- 【面向打野编程】——KMP算法入门
一.问题 咱们先不管什么KMP,来看看怎么匹配两个字符串. 问题:给定两个字符串,求第二个字符串是否包含于第一个字符串中. 为了具体化,我们以 ABCAXABCABCABX 与 ABCABCABX为例 ...
- KMP算法入门讲解
字符串匹配问题.假设文本是一个长度为$n$的字符串$T$,模板是一个长度为$m$的字符串$P$,且$m\leq n$.需要求出模板在文本中的所有匹配点$i$,即满足$T[i]=P[0],T[I+1]= ...
- HDU_1711_初识KMP算法
Number Sequence Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- KMP算法入门
学一把看毛片算法我觉得自己才能变得更加出色 明明昨天的题我都知道怎么模拟了,但是还是不会改KMP,是我学丑了 KMP是Knuth-Morris-Pratt三人设计的线性时间字符串匹配算法 nxt数组的 ...
- KMP算法——从入门到懵逼到了解
本博文參考http://blog.csdn.net/v_july_v/article/details/7041827 关于其它字符串匹配算法见http://blog.csdn.net/WINCOL/a ...
- KMP算法之从懵逼到入门
写本文的目的: 1.加深自己的理解,以便自己日后复习 2.给看到此文的人一点启发 KMP算法看懂了就觉得特别简单,思路也好理解,但是看不懂之前,查各种资料看大佬的博客,都很懵逼...... 1. 算 ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- KMP算法的Next数组详解
转载请注明来源,并包含相关链接. 网上有很多讲解KMP算法的博客,我就不浪费时间再写一份了.直接推荐一个当初我入门时看的博客吧:http://www.cnblogs.com/yjiyjige/p/32 ...
随机推荐
- lucene 检索流程整理笔记
- MySQL 5.5: InnoDB Change Buffering
To speed up bulk loading of data, InnoDB implements an insert buffer, a special index in the InnoDB ...
- 未能加载文件或程序集“XXX”或它的某一个依赖项。试图加载格式不正确的程序。
64位系统 IIS7.0配置.net网站时报错:未能加载文件或程序集"XXX"或它的某一个依赖项.试图加载格式不正确的程序. 背景: 在64位的操作系统中, IIS7.0配置.ne ...
- hibernate--HQL语法与详细解释
HQL查询: Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查询特性,因此 Hi ...
- Openjudge计算概论-DNA排序
/*===================================== DNA排序 总时间限制: 1000ms 内存限制: 65536kB 描述 给出一系列基因序列,由A,C,G,T四种字符组 ...
- JQuery Pagenation 知识点整理——$.extend(),与$.fn.extend()应用(20150517)
jQuery为开发插件提拱了两个方法,分别是: jQuery.fn.extend(); jQuery.extend(); 一. $.extend()方法 $.extend()方法在JQuery中有两个 ...
- linux下安装svn
linux下SVN服务器如何搭建和使用 | 浏览:12117 | 更新:2013-09-18 14:28 | 标签:linux linux下SVN服务器如何搭建和使用?说到SVN服务器,想必大家都知道 ...
- oracle11g服务项及其启动顺序
oracle安装完成后共七个服务,含义分别为: 1. Oracle ORCL VSS Writer Service:Oracle卷映射拷贝写入服务,VSS(Volume Shadow Copy Ser ...
- 运行ASP程序报错
错误提示: An error occurred on the server when processing the URL. Please contact the system administrat ...
- VBA 插入一行保留样式
Rows(processingRow).Insert ' 在指定的行数processingRow处插入一行 Rows(processingRow - 1).Select ' 选择上一行的整行 Sele ...