KMP算法匹配字符串

朴素匹配算法

  字符串的模式匹配的方法刚开始是朴素匹配算法,也就是经常说的暴力匹配,说白了就是用子串去和父串一个一个匹配,从父串的第一个字符开始匹配,如果匹配到某一个失配了,就重新去从父串的下一个字符开始匹配,这样的算法虽然理解起来容易,但是算法的时间复杂度无疑是很高的,假如父串是一个很长的字符串,而字串恰恰不和父串匹配,那无疑是对CPU的迫害。

  下面贴几张图看看这种朴素匹配算法:

但是第四个出现失配,就得重新让字串去和父串的第二个字符匹配,发现第二个也不匹配,只能再次匹配第三个,如下:

  这样下来时间复杂度大大变高,但是通过上帝视角我们可以发现其实第二个完全不用试,但是计算机不知道啊,所以我们就需要一个更好的算法来解决这个问题,这个算法就是要在朴素算法的基础上额外告诉计算机哪些地方不用尝试,可能我上面的这个例子举得不太恰当,但是这个算法的额外功能就是告诉了计算机如果某个位置失配了应该去尝试哪个位置。

  

KMP算法——和计算机的友好交流

  前面我们说KMP算法其实就是告诉计算机如果某个位置失配后应该往哪个位置回溯。而这个功能的实现其实只需要一个next数组,而这个数组也恰恰是这个算法的核心所在。

next数组

  这个数组里面存储的就是字串中每个位置失配后应该回溯的下标。举个例子,比如第9个元素失配后应该回溯到第3个再次匹配尝试,那就应该是next[9] = 3,值得注意的是,我们定义的串这个数据结构一般没有0号元素,所以next数组一样,next[0]没有意义。

  next数组该如何实现呢?

比如这块我们发现1-7和9-15都相等,而8和16不相等,那如果在第16个位置发生失配,就可以用1-7依次替代9-15的位置,用第8个再去匹配,如果匹配上了就继续往下匹配,未匹配就继续回溯。

代码实现(next数组):

void get_next(string son, int* next)
{
int i = 1; //下标
int j = 0; //回去的位置
next[1] = 0;
/*因为字符串未设置0号元素,所以next从1开始,默认为0,你应该懂我意思吧,回溯到0,你可能会问:
不是说好没有0号元素吗。你想啊,让字串的0号元素和父串的下一个匹配,难道不就是让字串的第一个和父串的
下一个匹配吗*/
while (i < son.len)
{
//如果这两个相等,即下标为i和j的元素相等,则当后面那个元素即i的下一个元素失配时,回溯到j的下一个元素,因为i和j的元素相等,所以保证了前面的一致,可以回溯
if (j == 0 || getch(son, i) == getch(son, j))
{
i++; j++; //精华,++后对应上面那句注释的 “当后面那个元素即i的下一个元素失配时,回溯到j的下一个元素”
if (getch(son, i) == getch(son, j)) //这里是一处优化,如果++后还相等,那你回溯回去肯定还失配啊,就再次回溯到你回溯的回溯
next[i] = next[j];
else
next[i] = j;
}
else //如果不相等,就将j回溯,i不能变,因为i一个一个加给next数组每个依次赋值
j = next[j];
}
}

KMP算法部分

  实现了next数组,剩下的就很简单了,利用next数组在失配时去回溯就ok了。

代码实现:

getch()函数是为了随机访问串

int kmp(string far, string son)
{
int next[255];
get_next(son, next);
int index = 1; //子串的下标索引
for (int i = 1; i <= far.len; i++) //遍历父串
{
while (index <= son.len)
{
if (getch(far, i) == getch(son, index))
{
index++; //如果匹配给子串+1
if (index == son.len + 1)
{
printf("成功!\n");
return i - son.len + 1;
}
break;
}
else
{
index = next[index];
if (index == 0)
{
index = 1;
break;
}
}
}
}
printf("失败!\n");
return 0;
}

字符串模式匹配——KMP算法的更多相关文章

  1. 字符串模式匹配KMP算法

    一篇不错的博客:http://www.cnblogs.com/dolphin0520/archive/2011/08/24/2151846.html KMP字符串模式匹配通俗点说就是一种在一个字符串中 ...

  2. 数据结构4.3_字符串模式匹配——KMP算法详解

    next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...

  3. 字符串匹配算法——KMP算法

    处理字符串的过程中,难免会遇到字符匹配的问题.常用的字符匹配方法 1. 朴素模式匹配算法(Brute-Force算法) 求子串位置的定位函数Index( S, T, pos). 模式匹配:子串的定位操 ...

  4. 字符串模式匹配sunday算法

    文字部分转自:http://www.cnblogs.com/mr-ghostaqi/p/4285868.html 代码是我自己写的 今天在做LeetCode的时候,碰到一个写字符串匹配的题目: htt ...

  5. 『字符串模式匹配 KMP』

    字符串模式匹配 我们要先了解一下问题是什么. 模式匹配是数据结构中字符串的一种基本运算,给定一个子串,要求在某个字符串中找出与该子串相同的所有子串,这就是模式匹配. KMP 然后我们来认识一下今天的主 ...

  6. 字符串匹配算法KMP算法

    数据结构中讲到关于字符串匹配算法时,提到朴素匹配算法,和KMP匹配算法. 朴素匹配算法就是简单的一个一个匹配字符,如果遇到不匹配字符那么就在源字符串中迭代下一个位置一个一个的匹配,这样计算起来会有很多 ...

  7. [Algorithm] 字符串匹配算法——KMP算法

    1 字符串匹配 字符串匹配是计算机的基本任务之一. 字符串匹配是什么?举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串& ...

  8. 模式匹配KMP算法

    关于KMP算法的原理网上有很详细的解释,我试着总结理解一下: KMP算法是什么 以这张图片为例子 匹配到j=5时失效了,BF算法里我们会使i=1,j=0,再看s的第i位开始能不能匹配,而KMP算法接下 ...

  9. 查找字符串的 KMP 算法

    查找字符串是我们平常编程过程中经常遇到的,现在介绍一种查找字符串算法,增加程序的执行速度. 通常我们是这么写的: /* content: search a string in a othor stri ...

随机推荐

  1. python实现十大核心算法(桶排没实例)

    # author:sevenduke # 2019-06-11 # 一.交换排序 # 排序算法的温故:冒泡排序 def dubblesort(arr): for i in range(0, len(a ...

  2. CodeForces - 1221E Game With String(不平等博弈)

    Alice and Bob play a game. Initially they have a string s1,s2,…,sns1,s2,…,sn, consisting of only cha ...

  3. POJ 1949 Chores

    Farmer John's family pitches in with the chores during milking, doing all the chores as quickly as p ...

  4. CodeForces985G Team Players

    G. Team Players time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  5. UWP 中的全局异常处理

    问题 在开发一款应用的过程中,我们开发者很难考虑到所有问题,往往会忘记处理一些可能发生的异常.随之而来的结果就是用户使用过程中接连不断的崩溃.所以,我们有必要处理所有未被我们处理的异常. 本文介绍了 ...

  6. vivado三人表决仿真

    概述 下面以三人表决电路的verilog仿真来了解一下vivado软件的使用. 编写设计文件 首先可以在开始的界面通过create new project来新建工程,也可以通过file-->pr ...

  7. 201871010119-帖佼佼《面向对象程序设计(java)》第十六周学习总结

    博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.co ...

  8. 8月份21道最新Java面试题剖析(数据库+JVM+微服务+高并发)

    前言 纵观几年来的Java面试题,你会发现每家都差不多.你仔细观察就会发现,HashMap的出现几率未免也太高了吧!连考察的知识点都一样,什么hash碰撞啊,并发问题啊!再比如JVM,无外乎考内存结构 ...

  9. 使用Pycharm轻轻松松脱下git版本控制高大上的外衣

    一.思考❓❔ 1.git操作难吗? git操作命令繁杂 需求复杂场景, 使用不易 原理深邃,对初学者来说是有难度的 2.那么难,还要学吗? 作为IT行业从业者(搬砖小工),不会Git?滚,出去~~~ ...

  10. html5 websocket 示例,websocket在线聊天,php websocket实例

    WebSocket在线测试工具 http://ws.douqq.com/ 1.连接格式为 ws://IP/域名:端口(示例ws://119.29.3.36:5354) 2.对于内网的测试环境,只需填入 ...