数据结构学习之字符串匹配算法(BF||KMP)
数据结构学习之字符串匹配算法(BF||KMP)
0x1 实验目的
通过实验深入了解字符串常用的匹配算法(BF暴力匹配、KMP、优化KMP算法)思想。
0x2 实验要求
编写出BF暴力匹配、KMP、优化KMP的代码模型
0x2 代码
0x2.1.1 BF暴力匹配
#include <iostream>
#include <string>
using namespace std;
int BF1(string s1,string s2)
{
int len=s2.length();
for(int i=0;i<s1.length();i++)
{
int n=len;
int j=i;
while(n)
{
//cout<< s1[j] <<endl;
if(s1[j++] != s2[len-n])
break;
n--;
}
if(n==0)
return i+1;
}
return -1;
}
int BF2(string s1,string s2)
{
int i=0;
int j=0;
while(i<s1.length() && j<s2.length())
{
if(s1[i]==s2[j])
{
i++;
j++;
}else
{
i=i-j+1;
j=0;
}
}
if(j>=s2.length())
return (i-j+1);
else
return -1;
}
int main()
{
string s1="asfasgasgsd";
string s2="asg";
cout<< BF1(s1,s2) <<endl;
cout<< BF2(s1,s2) <<endl;
return 0;
}
0x2.1.2 结果

0x2.1.3 体会
我写了两种,一开始我没看书自己意淫了第一种出来,代码不够书本简洁,本着向优秀代码学习的精神,还有对应对应下面KMP的匹配过程,第二种写法更有益于学习。过程主要是,while(i<s.length() && j<t.length())来判断退出,其中跟kmp不同的是,i需要i-j+1,j=0回溯,该算法的时间复杂度0(n*m)。
0x2.2 KMP || KMP优化
#include <iostream>
#include <string>
#define maxsize 200+7
using namespace std;
int next[maxsize];
int nextval[maxsize];
void GetNext(string s,int next[])
{
int j=0,k=-1;
next[0]=-1;
while(j<s.length()-1) //因为数组下标最大是s1.length()-1,下面是j++故j可以到达最大值
{
if(k==-1 || s[j]==s[k])
{
j++,k++;
next[j]=k;
}else
{
k=next[k];
}
}
}
void GetNextVal(string s,int nextval[])
{
int j=0,k=-1;
nextval[0]=-1;
while(j<s.length()-1)
{
if(k==-1 || s[j]==s[k])
{
j++,k++;
if(s[j]!=s[k])
nextval[j]=k;
else
nextval[j]=nextval[k];
}else
{
k=nextval[k];
}
}
}
//KMP优化
int KMPIndex1(string s,string t)
{
int i=0,j=0;
int next[maxsize];
GetNext(t,next);
while(i<s.length() && j<t.length())
{
if(j==-1 || s[i]==t[j])
{
i++,j++;
}else
{
j=next[j];
}
}
if(j>=t.length())
return(i-t.length());
else
return -1;
}
//KMP优化
int KMPIndex2(string s,string t)
{
int i=0,j=0;
int nextval[maxsize];
GetNextVal(t,nextval);
while(i<s.length() && j<t.length())
{
if(j==-1 || s[i]==t[j])
{
i++,j++;
}else
{
j=nextval[j];
}
}
if(j>=t.length())
return(i-t.length());
else
return -1;
}
int main()
{
string s="aaaaab";
string t="aaab";
cout<< KMPIndex1(s,t) <<endl;
cout<< KMPIndex2(s,t) <<endl;
return 0;
}
0x2.2.1 结果

0x2.2.2 体会
kmp算法主要思想是利用模式串自身的特点,避免主串的回溯过程,同时通过next数组,也减少了模式串的回溯长度。
首先是定义:
\\MAX \left \{ k|0<k<j\ 且 \ t_{0}t_{1}\cdots t_{k-1} = t_{j-k}t_{j-k+1}\cdots t_{j-1}\right \} \ 当此集合非空时
\\ 0 \qquad 其他情况
\end{matrix}\right.
\]
主要思想是:
比如一个模式串 ababb 显然前4个字符串满足 ab=ab 也就是$$t_{0}t_{1}=t_{2}t_{3}$$ 当你去用模式串去匹配串ababaababb的时候可以发现$$t_{4} \neq s_{4}$$,这个时候就直接可以跳转到 $$s_{2}$$ 开始 而不是从$$s_{1}$$开始,关于这个证明其实也很简单,如下:
aba $$\neq$$ bab 然后你发现这里了没有,从$$s_{1}$$开始其实就是从bab开始很明显就是不等,其实kmp就是这种规律,找出最大长度的前后缀,那么就确定了这个模式串滑动的长度,说的更简单点就是模式串包含了主串的信息,模式串跟主串的比较就可以转换为模式串跟自己的比较,就像上面的例子,通过反证法可以得到移动<next[j]的话必定会不想等。
代码重点是:
//初始化
next[0]=-1;
int j=0,k=-1;
while(j<s.length()-1)
{
if(k==-1 || s[j]==s[k])
{
j++,k++;
next[j]=k; //重点
}else
{
k=next[k]; //重点 abdbabc 显然c -> ab开头的两个字符,d不等于c,那么只能从a=c这里去比较了next[2]=0
}
}
0x3 最近学习总结
最近感觉自己特别浪,要学的东西还有很多,平时效率也好低,数据结构的作业也拖了好久,以前都是4天一次,这次竟然拖了那么10多天,最近要抓紧空闲时间去补回来了,下篇写一些递归的题目,介绍一些好玩的知识点。
数据结构学习之字符串匹配算法(BF||KMP)的更多相关文章
- 字符串匹配算法之 kmp算法 (python版)
字符串匹配算法之 kmp算法 (python版) 1.什么是KMP算法 KMP是三位大牛:D.E.Knuth.J.H.MorriT和V.R.Pratt同时发现的.其中第一位就是<计算机程序设计艺 ...
- Python 细聊从暴力(BF)字符串匹配算法到 KMP 算法之间的精妙变化
1. 字符串匹配算法 所谓字符串匹配算法,简单地说就是在一个目标字符串中查找是否存在另一个模式字符串.如在字符串 "ABCDEFG" 中查找是否存在 "EF" ...
- 字符串匹配算法之————KMP算法
上一篇中讲到暴力法字符串匹配算法,但是暴力法明显存在这样一个问题:一次只移动一个字符.但实际上,针对不同的匹配情况,每次移动的间隔可以更大,没有必要每次只是移动一位: 关于KMP算法的描述,推荐一篇博 ...
- 字符串匹配算法之kmp算法
kmp算法是一种效率非常高的字符串匹配算法,是由Knuth,Morris,Pratt共同提出的模式匹配算法,所以简称KMP算法 算法思想 在一个字符串中查找另一个字符串时,会遇到如下图的情况 我们通常 ...
- 动画演示Sunday字符串匹配算法——比KMP算法快七倍!极易理解!
前言 上一篇我用动画的方式向大家详细说明了KMP算法(没看过的同学可以回去看看). 这次我依旧采用动画的方式向大家介绍另一个你用一次就会爱上的字符串匹配算法:Sunday算法,希望能收获你的点赞关注收 ...
- 字符串匹配算法(三)-KMP算法
今天我们来聊一下字符串匹配算法里最著名的算法-KMP算法,KMP算法的全称是 Knuth Morris Pratt 算法,是根据三位作者(D.E.Knuth,J.H.Morris 和 V.R.Prat ...
- 字符串KMP——用途广泛的字符串匹配算法 + 扩展KMP——特殊定义的字符串匹配
引 入 引入 引入 " SY 和 WYX 在看毛片.(几 毛 钱买到的动作 片,毛 片) WYX 突然想回味一个片段,但是只记得台词里面有一句挺长的 " ∗ ∗ ∗ ∗ **** ...
- 字符串匹配算法——BF、KMP、Sunday
一:Brute force 从源串的第一个字符开始扫描,逐一与模式串的对应字符进行匹配,若该组字符匹配,则检测下一组字符,如遇失配,则退回到源串的第二个字符,重复上述步骤,直到整个模式串在源串中找到匹 ...
- 字符串匹配算法BF和KMP总结
背景 来看一道leetcode题目: Implement strStr(). Returns the index of the first occurrence of needle in haysta ...
随机推荐
- python3 集合 操作方法
今天都是课, 就学这么点 不多说 睡觉睡觉!!! #!usr/bin/env/ python # -*- coding:utf-8 -*- # Author:XiaoFeng list = [1,2 ...
- Storm入门(十三)Storm Trident 教程
转自:http://blog.csdn.net/derekjiang/article/details/9126185 英文原址:https://github.com/nathanmarz/storm/ ...
- 开源:ASP.NET Aries 开发框架(已支持.NET Core)
前言: 随着岁月的推进,不知不觉已在.NET这领域上战斗了十年了. 青春还没来得急好好感受,却已是步入健忘之秋的老人一枚了. 趁着还有点记忆,得赶紧把硬盘里那私藏的80G除外的东西,和大伙分享分享. ...
- Could not load file or assembly……
今天在运行一个ASP.NET Core项目的时候发现这样的错误: 我一开始觉得这是个很简单的问题,很明显,出错的原因是项目中某些地方还保留了对Njt.MvcAuthLib这个库的引用,而现在我不需要了 ...
- JS的常用正则表达式 验证密码(转载自用)
JS的正则表达式 强:字母+数字+特殊字符 ^(?![a-zA-z]+$)(?!\d+$)(?![!@#$%^&*]+$)(?![a-zA-z\d]+$)(?![a-zA-z!@#$%^& ...
- 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十一║Vue实战:开发环境搭建【详细版】
缘起 哈喽大家好,兜兜转转终于来到了Vue实战环节,前边的 6 篇关于Vue基础文章我刚刚简单看了看,感觉写的还是不行呀,不是很系统,所以大家可能看上去比较累,还是得抽时间去润润色,修改修改语句和样式 ...
- 老毛桃pe安装系统
1.准备一个空白U盘,插入电脑. 2.下载老毛桃pe 3.下载完成后,打开老毛桃,默认制作成系统盘,傻瓜操作,无需修改参数 4.打开浏览器,下载要安装的系统 www.msdn.itellyou.cn ...
- 安装Phalcon报错:gcc: Internal error: Killed (program cc1)
起因 安装Phalcon可以参考github上面的README.md 下面是我在阿里云ECS服务器上面执行命令的过程: # 安装依赖 sudo yum install php-devel pcre-d ...
- 一套代码小程序&Web&Native运行的探索03——处理模板及属性
接上文:一套代码小程序&Web&Native运行的探索02 对应Git代码地址请见:https://github.com/yexiaochai/wxdemo/tree/master/m ...
- C#代码安装Windows服务(控制台应用集成Windows服务)
最近在为一款C/S架构的科研软件开发云计算版,需要用到WCF,考虑到不需要什么界面以及稳定性,无人值守性,准备用Windows Service作为宿主,无奈Windows Service的安装太为繁复 ...