KMP初步
KMP算法专门用于处理字符串匹配问题。
开始学习的时候觉得很有道理,但是一些细节总觉得有些模糊,所以一直觉得懵懵懂懂。今天思考了一下,总结一下,希望对大家也有帮助。
朴素的字符串匹配算法就是一个一个字符挨个去试,但是当匹配串长度比较长的时候复杂度显然会爆炸。
为了解决这个问题,很厉害的三个人想出来了这个很厉害的算法。
核心思想是假如比较到第j+1个字符的时候匹配失败,不是像朴素算法一样从头开始比较,而是利用匹配串自身的特性直接跳转到匹配串头部,这个头部和尾部相同。这是比较容易理解的,显然这样做是正确的,但是为什么能够保证不会漏掉可能存在的其他匹配串呢?
现在我们用反证法来看这个问题:即假在串s1中查找串s2,如果比较到si的第i个元素,s2的第j个元素,发现s1[i+1]!=s2[j+1],此时我们可以直接跳转到s2[p[j]]处继续匹配s1和s2,p[j]是指s2[1..p[j]]和s2[i-p[j]+1..i]相同的最大p[j],现在证明这样做不会漏掉前面(s1[i-j+1..i-p[j]+1]这些部分是没有进行比较的)可能存在的其他串。
假如在那个区域存在与s2匹配的串,因为长度问题,这个串结束的部分一定超过i,而这个串在i前面的部分和s2[1..j]相同,但是它比最大的p[j]还长,这样的串是不可能存在的,同时也说明了为什么KMP需要最大的p[j]。
现在基本思想已经证明正确,所要做的就是思考如何实现这个算法了。问题主要有两个:如何得到p[j]和如何实现匹配算法。
为了方便理解,这里先介绍如何实现匹配算法:
1 void kmp()
2 {
3 j=0;//匹配串的指针
4 for(int i=0;i<n;i++) //之所以是小于n是因为会判断i+1处的值
5 {
6 while(j>0 && a[i+1]!=b[j+1]) j=p[j];//j>0说明在j前面存在匹配,存在匹配而出现不匹配就要将j指针前移到和末尾相同而且下一位支持匹配的地方
7 if(b[j+1]==a[i+1]) ++j;
8 if(j==m)
9 {
10 printf("%d",i+1-m+1);//直接输出匹配位置
11 j=p[j]; //继续寻找(可重叠)匹配
12 //j=0; 寻找不重叠匹配
13 }
14 }
15 }
这个过程的复杂度为O(n),具体为什么需要进行摊还分析(我也不是太懂。。。)。
然后我们就要考虑如何得到p[j]了。
我们不难发现(不难个鬼哦),在求p[j]的过程其实就是在前j-1个字符中查找第j个位置组成的子串的过程,因此得到p[j]的过程其实和上述过程类似不同之处在于每次查找结束后都要更新那个位置的p[j]的值。
1 void pre()
2 {
3 p[1]=0;
4 j=0; //j指i所匹配的位置
5 for(int i=1;i<m;i++)
6 {
7 while(j>0 && b[j+1]!=b[i+1]) j=p[j];
8 if(b[i+1]==b[j+1]) ++j;
9 p[i+1]=j;
10 }
11 }
大概就是这样,嗯~
KMP初步的更多相关文章
- kmp算法初步理解
123456789 abbdaxnds Next 01212 第三位看第二位b,第二位和第三位相同,都是b,所以第三位的next是第二位的next加1,即1+1=2 第四位看第三位b,第四位d与第 ...
- Number Sequence HDU 1711(KMP)
http://acm.hdu.edu.cn/showproblem.php?pid=1711 首次接触KMP,自己都不是特别理解.在网上百度看了好几个帖子之后,对KMP也有了初步的理解. #inclu ...
- KMP算法中next函数的理解
首先要感谢http://blog.csdn.net/v_july_v/article/details/7041827以及http://blog.chinaunix.net/uid-27164517-i ...
- KMP算法具体解释(转)
作者:July. 出处:http://blog.csdn.net/v_JULY_v/. 引记 此前一天,一位MS的朋友邀我一起去与他讨论高速排序,红黑树,字典树,B树.后缀树,包含KMP算法,只有在解 ...
- 完全掌握KMP算法思想
文档下载页面http://download.csdn.net/detail/yedeqixian/4209500 80页在讲KMP算法的开始先举了个例子,让我们对KMP的基本思想有了最初的认 ...
- KMP字符串匹配 简单理解
http://www.cnblogs.com/c-cloud/p/3224788.html 字符串匹配,长串长度为m,子串长度为n 则,暴力破解的复杂度为o(m*n) 如果用kmp匹配,则复杂度为o( ...
- 字符串匹配(KMP 算法 含代码)
主要是针对字符串的匹配算法进行解说 有关字符串的基本知识 传统的串匹配法 模式匹配的一种改进算法KMP算法 网上一比較易懂的解说 小样例 1计算next 2计算nextval 代码 有关字符串的基本知 ...
- POJ2406 Power Strings —— KMP or 后缀数组 最小循环节
题目链接:https://vjudge.net/problem/POJ-2406 Power Strings Time Limit: 3000MS Memory Limit: 65536K Tot ...
- 移动端之Android开发的几种方式的初步体验
目前越来越多的移动端混合开发方式,下面列举的大多数我都略微的尝试过,就初步的认识写个简单的心得: 开发方式 开发环境 是否需要AndroidSDK 支持跨平台 开发语言&技能 MUI Win+ ...
随机推荐
- 【原创】大叔问题定位分享(23)Ambari安装向导点击下一步卡住
ambari安装第一步是输入集群name,点击next时页面卡住不动,如下图: 注意到其中一个接口请求结果异常,http://ambari.server:8080/api/v1/version_def ...
- Monkey自动化脚本(一)
1.Monkey简介 Monkey-猴子,通过Monkey程序模拟用户触摸屏幕.滑动Trackball. 按键等操作来对设备上的程序进行压力测试,检测程序多久的时间会发生异常,主要用于Android ...
- HTTP Status 500 - java.lang.reflect.InvocationTargetException
type Exception report message java.lang.reflect.InvocationTargetException description The server enc ...
- 饮冰三年-人工智能-Python-19 Python网络编程
Socket:套接字.作用:我们只需要安照socket的规定去编程,就不需要深入理解tcp/udp协议也可以实现 1:TCP协议 1.1 客户端服务端循环收发消息 # 1:引入stock模块(导包) ...
- 微信支付没有结果通知,notify_url参数的接口没有收到微信支付结果通知
在微信支付统一下单的时候需要填一个notify_url参数用于处理微信支付结果通知 但是,有时候我们发现我们设置的这个接口收不到微信请求.原因有一下几个,大家一一对照,也欢迎补充. 1. url是否可 ...
- [iOS11] contentInsetAdjustmentBehavior 问题, push back时, 界面会上下移动.
https://stackoverflow.com/questions/45573829/weird-uitableview-behaviour-in-ios11-cells-scroll-up-wi ...
- jQuery的下拉选select2插件用法
1转自:https://www.jb51.net/article/95561.htm 用了这么久的Select2插件,也该写篇文章总结总结.当初感觉Select2不是特别好用,但又找不到比它更好的下拉 ...
- UOJ#314. 【NOI2017】整数 其他
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ314.html 题解 如果只加不减,那么瞎势能分析一波可以知道暴力模拟的复杂度是对的. 但是有减法怎么办? ...
- 2017-2018 Northwestern European Regional Contest (NWERC 2017)
A. Ascending Photo 贪心增广. #include<bits/stdc++.h> using namespace std; const int MAXN = 1000000 ...
- Java反射通过getter和setter方法实现类的拷贝
private User copyFieldValues(User userData, User user) { Field[] fields = user.getClass().getDeclare ...