KMP算法匹配原理以及C++实现
原创作品,转载请注明出处:点我





#ifndef __KMP__H__
#define __KMP__H__
#include <string>
#include <vector>
using namespace std; class KMP{
public:
//void static getNext(const string &str,vector<int> &vec);
int kmp();
KMP(){}
KMP( const string &target,const string &pattern):mTarget(target),mPattern(pattern){}
void setTarget(const string &target);
void setPattern(const string &pattern);
private:
vector< int> mVec;
string mTarget;
string mPattern;
void getNext();
};
#endif
下面是源代码实现
#include "KMP.h"
#include <iostream>
#include <vector>
using namespace std; //获取字符串str的所有子串中相同子集的长度
//比如字符串ababacb,分别获取字符串a,ab,aba,abab,ababa,ababac,ababacb中D
//最前面和最后面相同的子串的最大长度,比如
//a:因为aa为a单个字符,所以最前面和最后面相同的子串的最大长度为a0
//aba,最前面一个a和最后面一个元a素a相同,所以值为a1,abab最前面2个ab和最后面两个ab相同,值为a2
//ababa最前面3个为aaba,最后面3个为aaba,所以值为a3
void KMP::getNext()
{
mVec.clear(); //清空?ec
//vec.push_back(0);//为a了使用方便,vec的第一个数据不用
mVec.push_back(); //第一个字符的下一个位置一定是0,比如"ababacb",首字符a的值为0
string::const_iterator start = mPattern.begin();
string::const_iterator pos = start + ;
while(pos != mPattern.end())
{
string subStr(start,pos+); //获取子字符串
int strLen = subStr.size() - ;//获取子串中D前后相同的子子串的最大长度
do
{
string prefix(subStr,,strLen); //获取subStr中D的前面strLen子集
string postfix(subStr,subStr.size()-strLen,strLen); //获取subStr中D的前面?trLen子集
if(prefix == postfix)
{
mVec.push_back(strLen);
break;
}
--strLen;
/如果前后相同的子集的长度小于一
/说明没有相同的,则把0压栈
if(strLen < )
mVec.push_back();
} while(strLen > ); ++pos;
}
} void KMP::setPattern(const string &pattern)
{
mPattern = pattern;
} void KMP::setTarget(const string &target)
{
mTarget = target;
} int KMP::kmp()
{
getNext(); //首先获取next数据
int targetIndex = ;
int patternIndex = ;
int headIndex = ;//指向跟pattern匹配的Target的第一个元素的索引
while(patternIndex != mPattern.size() && targetIndex != mTarget.size())
{
for(int i = ; i < mPattern.size()-;++i)
{
if(mPattern[patternIndex] == mTarget[targetIndex])
{
++patternIndex;
++targetIndex;
if(mPattern.size()== patternIndex)//如果已经匹配成功,则退出循环
break;
}
else
{
if( == patternIndex)//如果第一个字符就不匹配,则把mTarget左移一位
++headIndex;
else
{
headIndex += patternIndex - mVec[patternIndex-];//由于vector索引从零开始,所以要减去一
patternIndex = mVec[patternIndex-];//更新patternIndex索引
}
targetIndex = headIndex + patternIndex;//跟新targetIndex索引
break;
} }
} return headIndex;
}
KMP算法匹配原理以及C++实现的更多相关文章
- 字符串匹配--kmp算法原理整理
kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...
- [Algorithm] 字符串匹配算法——KMP算法
1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...
- 深入理解KMP算法
前言:本人最近在看<大话数据结构>字符串模式匹配算法的内容,但是看得很迷糊,这本书中这块的内容感觉基本是严蔚敏<数据结构>的一个翻版,此书中给出的代码实现确实非常精炼,但是个人 ...
- KMP算法详解 --- 彻头彻尾理解KMP算法
前言 之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k. 但是问题在于如何求出这个最大前后缀长度呢? 我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破, 后来翻看 ...
- 模式匹配KMP算法
关于KMP算法的原理网上有很详细的解释,我试着总结理解一下: KMP算法是什么 以这张图片为例子 匹配到j=5时失效了,BF算法里我们会使i=1,j=0,再看s的第i位开始能不能匹配,而KMP算法接下 ...
- 数据结构(复习)---------字符串-----KMP算法(转载)
字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...
- KMP算法详解 --从july那学的
KMP代码: int KmpSearch(char* s, char* p) { ; ; int sLen = strlen(s); int pLen = strlen(p); while (i &l ...
- KMP算法的一次理解
1. 引言 在一个大的字符串中对一个小的子串进行定位称为字符串的模式匹配,这应该算是字符串中最重要的一个操作之一了.KMP本身不复杂,但网上绝大部分的文章把它讲混乱了.下面,咱们从暴力匹配算法讲起,随 ...
- 字符串匹配KMP算法详解
1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有比较详细的通俗易懂的讲解,另一方面也怪自己没有沉下心来研究.最近在leetcode上又遇见字符串匹配的题目,以此 ...
随机推荐
- eclipse安装插件的方式 三种:links、eclipse中使用插件安装向导安装、直接copy插件到对应的eclipse目录 MyEclipse10安装SVN插件
myeclipse安装插件 1.直接将插件copy到myeclipse目录下的dropins目录下(没有目录就新建一个),重启,详细参考 MyEclipse使用总结——MyEclipse10安装SVN ...
- http://www.cnblogs.com/txw1958/p/alipay-f2fpay.html
一.条码支付及二维码支付介绍 1. 条码支付 条码支付是支付宝给到线下传统行业的一种收款方式.商家使用扫码枪等条码识别设备扫描用户支付宝钱包上的条码/二维码,完成收款.用户仅需出示付款码,所有收款操作 ...
- RHEL7 -- nmcli的使用
查看网络设备的状态: # nmcli dev status DEVICE TYPE STATE ens32 --ethernet connected eth1 --ethernet disconnec ...
- Linux内核同步 - sleepable RCU的实现
一.前言 由于曾经在Linux2.6.23上工作了多年,我对这个版本还是非常有感情的(抛开感情因素,本来应该选择longterm的2.6.32版本来分析的,^_^),本文主要就是描述Linux2.6. ...
- Spark Core Runtime分析: DAGScheduler, TaskScheduler, SchedulerBackend
Spark Runtime里的主要层次分析,梳理Runtime组件和运行流程, DAGScheduler Job=多个stage,Stage=多个同种task, Task分为ShuffleMapTas ...
- jquery data方法获取某个元素上事件
获取某个元素上的事件,jquery的给元素绑定的事件可以用data方法取出来. 通过$(element).data("events")来获取 // 比如给一个button绑定两个c ...
- 【Android】12.0 第12章 Intent及其过滤器—本章示例主界面
分类:C#.Android.VS2015: 创建日期:2016-02-23 一.简介 这一章我们主要学习Intent的基本用法,并通过例子演示如下功能: 如何启动另一个界面: 如何获取另一个界面的返回 ...
- Jquery获得子页面中某个元素
本页面中有子框架iframe1.获取iframe1中元素 $("input[name$='svNo']", window.frames["iframe1"].d ...
- ping域名和ping IP时速度不同的原因
不知道大家在ping的时候有没有遇到过这样的问题:当你ping一个域名的时候,ping结果返回得很慢,但是如果直接ping这个域名的ip,结果却快很多. 直接ping ip的时候,每两次发包之间没有明 ...
- 基于乐观锁的配置server与XServer的交互
XServer与配置server,配置server保存有XServer的配置文件里的信息. 怎样在项目启动时.让XServer从配置server中获取到自己的配置信息,并达到通信资源的节省与控制. 通 ...