KMP字符串模式匹配算法(C++实现)
鉴于原理有点复杂,详细原理可以参考这篇文章http://blog.csdn.net/v_july_v/article/details/7041827
本文直接从结论入手,应付考试和竞赛足够了。
设T为目标串("aaabbbaabbabcabcabbaba"),pat为模式串("aabbabc")。
这是模式串的next数组:
| j(下标) | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
| pat | a | a | b | b | a | b | c |
| next[j] | -1 | 0 | 1 | 0 | 0 | 1 | 0 |
KMP算法:
j=0时,next[j]=-1。表示下一趟匹配比较时,模式串的第-1个字符与目标串上次失配的位置对齐。(其实等同于第0个字符与目标串上次失配的下一个位置对齐),模式串需要移动到posT-next[j]的位置。(posT为T串下标)
j=1时,next[j]=0。表示下一趟匹配比较时,模式串的第0个字符与目标串上次失配的位置对齐。模式串需要移动到posT-next[j]个位置。
j=2时,next[j]=1。表示下一趟匹配比较时,模式串的第1个字符与目标串上次失配的位置对齐。模式串需要移动到posT-next[j]个位置。
以此类推......
那么下面只要求出next数组即可,next数组是如何形成的?
从下标0开始,一直到lengthP-1为止(lengthP是模式串的长度),每次寻找该下标前面前缀与后缀相同的最大长度(前后缀不包括前面整个字符串,即起始位置和终止位置都相等的那一个字符串,下面有解释)。
j=0时,字符a前面无字符,故标记-1;
j=1时,字符a前面有字符a,但由于“前后缀不包括前面整个字符串”的规则,所以并没有相同的前后缀一说,故标记为0。
j=2时,字符b前面有字符aa,前后缀相同的字符串为a,故标记为前后缀的长度1。
以此类推......(PS:前后缀的计算都是从左到右的)
其实这样说是为了方便理解next数组,而next数组的实际形成也是一次KMP算法,它也是一个匹配字符串的过程,用后缀去匹配前缀的过程。
代码如下:
#include<iostream>
#include<string>
using namespace std;
string T;
string pat;
void getNext(int next[],int lengthP){//lengthP为模式串P的长度
int j=,k=-;//j为P串的下标,k用来记录该下标对应的next数组的值
next[]=-;//初始化0下标下的next数组值为-1
while(j<lengthP){ //对模式串进行扫描
if(k==-||pat[j]==pat[k]){//串后缀与前缀没有相等的子串或者此时j下标下的字符与k下的字符相等。
j++;k++;
next[j]=k;//设置next数组j下标的值为k
}else
k=next[k];//缩小子串的范围继续比较
}
} int kmp(int k,int next[]){
int posP=,posT=k;//posP和posT分别是模式串pat和目标串T的下标,先初始化它们的起始位置
int lengthP=pat.length();//lengthP是模式串pat长
int lengthT=T.length();//lengthT是目标串T长
while(posP<lengthP&&posT<lengthT){//对两串扫描
if(posP==-||pat[posP]==T[posT]){//对应字符匹配
posP++;posT++;
}else
posP=next[posP];//失配时,用next数组值选择下一次匹配的位置
}
if(posP<lengthP) return -;
else return posT-lengthP;//匹配成功
} int main(){
T="aaabbbaabbabcabcabbaba";
pat="aabbabc";
int lengthP=pat.length();
int next[lengthP]={};
getNext(next,lengthP);
int pos=kmp(,next);
cout<<pos<<endl;
cout<<"next[]:";
for(int i=;i<lengthP;i++){
cout<<next[i]<<" ";
}
return ;
}
KMP字符串模式匹配算法(C++实现)的更多相关文章
- [转] 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
字符串模式匹配算法——BM.Horspool.Sunday.KMP.KR.AC算法一网打尽 转载自:http://dsqiu.iteye.com/blog/1700312 本文内容框架: §1 Boy ...
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
字符串模式匹配算法——BM.Horspool.Sunday.KMP.KR.AC算法一网打尽 本文内容框架: §1 Boyer-Moore算法 §2 Horspool算法 §3 Sunday算法 §4 ...
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法
ref : https://dsqiu.iteye.com/blog/1700312 本文内容框架: §1 Boyer-Moore算法 §2 Horspool算法 §3 Sunday算法 §4 KMP ...
- 字符串模式匹配算法--BF和KMP详解
1,问题描述 字符串模式匹配:串的模式匹配 ,是求第一个字符串(模式串:str2)在第二个字符串(主串:str1)中的起始位置. 注意区分: 子串:要求连续 (如:abc 是abcdef的子串) ...
- Java数据结构之字符串模式匹配算法---Brute-Force算法
模式匹配 在字符串匹配问题中,我们期待察看源串 " S串 " 中是否含有目标串 " 串T " (也叫模式串).其中 串S被称为主串,串T被称为子串. 1.如果在 ...
- Java数据结构之字符串模式匹配算法---KMP算法2
直接接上篇上代码: //KMP算法 public class KMP { // 获取next数组的方法,根据给定的字符串求 public static int[] getNext(String sub ...
- Java数据结构之字符串模式匹配算法---KMP算法
本文主要的思路都是参考http://kb.cnblogs.com/page/176818/ 如有冒犯请告知,多谢. 一.KMP算法 KMP算法可以在O(n+m)的时间数量级上完成串的模式匹配操作,其基 ...
- 字符串模式匹配算法1 - BF和KMP算法
在字符串S中定位/查找某个子字符串P的操作,通常称为字符串的模式匹配,其中P称为模式串.模式匹配有多种算法,这里先总结一下BF算法和KMP算法. 注意:本文在讨论字符位置/指针/下标时,全部使用C语法 ...
- 字符串模式匹配算法系列(二):KMP算法
算法背景: KMP算法是由Donald Knuth和Vaughan Pratt于1970年共同提出的,而James H.Morris也几乎同时间独立提出了这个算法.因此人们将其称作“克努特-莫里斯-普 ...
随机推荐
- cent os 7 与cent os 6区别
原文地址:https://www.cnblogs.com/Csir/p/6746667.html 前言 centos7与6之间最大的差别就是初始化技术的不同,7采用的初始化技术是Systemd,并行的 ...
- Linux命令大杂烩
查看linux出口IP curl ifconfig.me scp跨服务器转移文件命令 scp 文件 root@IP:/application/apache-tomcat-8.0.36 回车, ...
- Migrating Brokers in a Cluster
Brokers can be moved to a new host in a Kafka cluster. This might be needed in the case of catastrop ...
- ckeditor django admin 中使用
ckeditor settings配置 ############ # CKEDITOR # ############ MEDIA_ROOT = os.path.join(BASE_DIR, 'medi ...
- WPF C# 命令的运行机制
1.概述 1.1 WPF C# 命令的本质 命令是 WPF 中的输入机制,它提供的输入处理比设备输入具有更高的语义级别. 例如,在许多应用程序中都能找到的“复制”.“剪切”和“粘贴”操作就是命令. W ...
- 七 Struts2 文件上传和下载
配置文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC &qu ...
- 360 随身 WiFi3 在 Ubuntu 14.04 下的使用
由于 360 随身 WiFi3 采用 Mediaek 代号 0e8d:760c 的芯片,目前没有官方或第三方 Linux 驱动,所以造成 Linux 用户的诸多困扰. 本文给出一个迂回的解决方案:在 ...
- PS教程:抠透明冰块
1.打开我们需要用到的素材,ctrl+a全选,ctrl+c复制 2.接下来给图层添加一个图层蒙版,按alt键点击图层蒙版,看到它变成白色了 3.ctrl+v,把刚才复制好的图粘贴进来 4.接着ctrl ...
- 搭建SpringMVC+Hibernate
1.首先加入相关的jar包,配置web.xml文件,如下: <?xml version="1.0" encoding="UTF-8"?> <w ...
- jexus独立版设置支持https
先用命令找到libssl.so find / -name libssl.so.* 执行完命令之后找到libssl.so.x.x.x如(libssl.so.1.0.0) 再到jexus/runtime/ ...