王道数据结构课代表 - 考研数据结构 第四章 串-KMP(看毛片算法) 究极精华总结笔记(C版本)

本篇博客是考研期间学习王道课程 传送门 的笔记,以及一整年里对数据结构知识点的理解的总结。希望对新一届的计算机考研人提供帮助!!!
 
关于对 章节知识点总结的十分全面,涵括了《王道数据结构》课程里的全部要点本人来来回回过了三遍视频),其中还陆陆续续补充了许多内容,所以读者可以相信本篇博客对于考研数据结构“串”章节知识点的正确性与全面性
但如果还有自主命题的学校,还需额外读者自行再观看对应学校的自主命题材料
 
数据结构与算法 笔记导航🚥🚥🚥

  1. 🥬 第一章 绪论(无)
  2. 🥕 第二章 线性表
  3. 🥪 第三章 栈和队列
  4. 🍊 第四章 串-KMP(看毛片算法) ⇦当前位置🪂
  5. 🍒 第五章 树和二叉树
  6. 🍀 第六章 图
  7. 🍚 第七章 查找(B树、散列表)
  8. 🧄 第八章 排序 (内部排序:八大排序动图演示与实现 + 外部排序)
  9. 🍔 数据结构与算法 复试精简笔记 (未完成)
  10. 🎨 408 全套初复试笔记汇总 传送门 🏃‍🏃‍🏃‍
     

如果本篇文章对大家起到帮助的话,跪求各位帅哥美女们,求赞👍 、求收藏 👏、求关注!👀
你必考上研究生!我说的,耶稣来了也拦不住!😀😀😀

在这里插入图片描述

 

精准控时:
如果不实际操作代码,只是粗略过一下知识点,需花费 30 分钟左右过一遍
这个30分钟是我在后期冲刺复习多次尝试的时间,可以让我很好的在后期时间紧张的阶段下,合理分配复习时间;
但是刚开始看这份博客的读者也许会因为知识点陌生、笔记结构不太了解,花费许多时间,这都是正常的。
重点!!!学习一定要多总结多复习!重复、重复、再重复!!!

食用说明书:
第一遍学习王道课程时,我的笔记只有标题和截图,后来复习发现看只看图片,并不能很快的了解截图中要重点表达的知识点。
所以再第二遍复习中,我给每一张截图中标记了重点,以及每张图片上方总结了该图片对应的知识点以及自己的思考
最后第三遍,查漏补缺。
所以 ,我把目录放在博客的前面,就是希望读者可以结合目录结构去更好的学习知识点,之后冲刺复习阶段脑海里可以浮现出该知识结构,做到对每一个知识点熟稔于心!
请读者放心!目录展示的知识点结构是十分合理的,可以放心使用该结构去记忆学习!
注意(⊙o⊙)!,每张图片上面的文字,都是该图对应的知识点总结,方便读者更快理解图片内容。

 


第4章 串

4.1 串的定义和实现

在这里插入图片描述

4.1.1 串的定义

  • 子串:串中任意的连续的字符(空串也可以是子串)
  • 主串
  • 位置:位序

在这里插入图片描述

  • 串也是线性表(数据类型有限制)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.1.2 串的存储结构

1、串的顺序存储

在这里插入图片描述

在这里插入图片描述

2、串的链式存储
  • 链式存储缺点:存储密度低
  • 你会发现为了存储char类型的数据,反而还搭配了一个占据空间更大的指针,无疑是浪费!
  • 改进:提高结点里数据域所能表示的数据量

在这里插入图片描述

3、串的基本操作

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4、4.1.2小结

在这里插入图片描述


4.2 串的模式匹配

4.2.1 简单的模式匹配算法

  • 模式匹配:在主串中找到与模式串相同的子串
  • 模式串与子串不是一个概念,未必在主串中存在
  • 下图中的红字在描述上不是那么准确(有误会),不过大致意思要明白

在这里插入图片描述

  • 朴素模式匹配算法:暴力匹配

在这里插入图片描述

1、具体代码

在这里插入图片描述

在这里插入图片描述

2、分析算法性能
  • 算法性能分析在图中已经介绍的很清楚了,这里不再解释了

在这里插入图片描述

在这里插入图片描述

3、4.2.1小结

在这里插入图片描述


4.2.2 改进的模式匹配算法——KMP算法

1、算法思想
  • 主要思想:当模式匹配失败时,该回溯到哪里呢?
  • 看下图中“关键”指出的next[]数组

在这里插入图片描述

2、初步代码

在这里插入图片描述

3、常考:求模式串的next数组
  • 本节探讨:手算方式求模式串的next数组
例子

在这里插入图片描述

在这里插入图片描述

方法总结
  • 后缀指的是主串,前缀指的是模式串
  • 前缀后缀都是指一个串里截取部分串(连续)出来,只是前缀必须有第一个字符,不能有最后一个字符
  • 后缀同理
  • 其实这种方法总结太麻烦了,不如直接自己看,next[i]选择能匹配最多字符的位置
  • 例如next[7]可以等于5,也可以等于3,但是优先选择3
  • 注意注意注意!
    • 后缀的尾对前缀的头,后缀在上前缀在下

在这里插入图片描述

练习
  • next[1]一定为0,next[2]一定为1
  • 模式串第一个元素不匹配,next[1]为0就是说:主串直接匹配下一个
  • 模式串第二个元素不匹配,只能从一个重新匹配了
  • 模式串第三个元素不匹配,这个时候才考虑从第一个还是第二个开始匹配
  • 所以,做题直接考虑第三个

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4、KMP算法性能分析
  • O(m):模式串的长度m
  • O(n):主串的长度n

在这里插入图片描述

5、4.2.2小结
  • KMP的关键思想:主串的扫描指针i不回溯(i一直+1),模式串的扫描指针j回溯
  • KMP还存在缺陷

在这里插入图片描述


4.2.3 KMP的进一步优化 —— nextval数组

  • 当主串的第4个字符和模式串的第4个字符发生不匹配时
  • next[4]=1,可是模式串1位置和4位置一样都是g,还是和l不匹配,这样就多余一次

在这里插入图片描述

在这里插入图片描述

算法总结

在这里插入图片描述

上面图片中的案例解析:

步骤原因操作
1nextva[1] = 0
2next[2]==1 看S[1] && a!=bnextva[2] = next[2] =1
3next[3]1 看S[1] && aanextva[3] = nextva[1]
4next[4]2 看S[2] && bbnextva[4] = nextva[2]
5next[5]3 看S[3] && aanextva[5] = nextva[3]
6next[6]=4 看S[4] && b!=anextva[6] = next[6] = 4

考验人加油!!!

  • 17
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
KMP算法是一种字符匹配算法,可以在一个主中查找一个模式是否出现。这里提供一个用C语言实现的KMP算法。 首先,需要定义一个函数`get_next`,用于计算模式的next数组。next数组是一个长度为模式长度的整型数组,表示当匹配失败时,模式应该向右移动的位数。 ```c void get_next(char* pattern, int* next) { int i = 0, j = -1; next[0] = -1; while (i < strlen(pattern)) { if (j == -1 || pattern[i] == pattern[j]) { i++; j++; next[i] = j; } else { j = next[j]; } } } ``` 接下来,定义一个函数`kmp`,用于在主中查找模式。函数的参数包括主指针、主长度、模式指针、模式长度和next数组。 ```c int kmp(char* text, int text_len, char* pattern, int pattern_len, int* next) { int i = 0, j = 0; while (i < text_len && j < pattern_len) { if (j == -1 || text[i] == pattern[j]) { i++; j++; } else { j = next[j]; } } if (j == pattern_len) { return i - j; } else { return -1; } } ``` 下面是一个完整的示例代码: ```c #include <stdio.h> #include <string.h> void get_next(char* pattern, int* next) { int i = 0, j = -1; next[0] = -1; while (i < strlen(pattern)) { if (j == -1 || pattern[i] == pattern[j]) { i++; j++; next[i] = j; } else { j = next[j]; } } } int kmp(char* text, int text_len, char* pattern, int pattern_len, int* next) { int i = 0, j = 0; while (i < text_len && j < pattern_len) { if (j == -1 || text[i] == pattern[j]) { i++; j++; } else { j = next[j]; } } if (j == pattern_len) { return i - j; } else { return -1; } } int main() { char text[] = "ABABABABCABAAB"; char pattern[] = "ABABCABAA"; int text_len = strlen(text); int pattern_len = strlen(pattern); int next[pattern_len]; get_next(pattern, next); int pos = kmp(text, text_len, pattern, pattern_len, next); if (pos == -1) { printf("Pattern not found.\n"); } else { printf("Pattern found at position %d.\n", pos); } return 0; } ``` 输出结果为: ``` Pattern found at position 6. ``` 表示在主中找到了模式,并且位置为6。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力的clz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值