—— —— —— —— —— —— —— —— —— —— —— —— —— ——
- 接下来进一步思考滑动策略的细节:不匹配时 , 应当滑动到哪里?
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/15162a159-35.png)
文章插图
首先 , 把主串和模式串的首位对齐 , 从左到右对逐个字符进行比较 。
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516292592-36.png)
文章插图
第一轮 , 发现前5个字符都是匹配的 , 第6个字符不匹配 , 将其标记为坏字符 ‘A’ 。
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516295404-37.png)
文章插图
【重难点】
可以发现 , 在好前缀 “GTGTG” 当中 , 主串的好前缀的后三个字符 “GTG” 和模式串的前三位字符 “GTG” 是相同的 。我们分别把这两部分记作可匹配后缀子串与可匹配前缀子串 。在之后的比较中 , 这两部分一定能够匹配上 。并且在这两个部分匹配上之前 , 一定没有其他可能使得模式串成功匹配的情况 , 这也为选择最长的子串进行滑动提供了保障 。因此 , 我们直接将模式串后移两位 , 使得这两部分对齐 , 并开始下一次比较 , 省去了中间的无效比较 。
同理 , 如果在好前缀中如果存在多个可匹配后缀子串 , 那么为了能省区更多的无效比较 , 我们选择找到最长的子串进行滑动 。因此 , 我们的滑动策略为:在主串的好前缀中 , 找到最长可匹配后缀子串;在模式串中 , 找到对应的最长可匹配前缀子串 。
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516294516-38.png)
文章插图
第二轮 , 我们直接把模式串向后移动两位 , 让两个 “GTG” 对齐 , 继续从刚才主串的坏字符 ‘A’ 开始进行比较 。
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516295F7-39.png)
文章插图
此时 , 主串的字符 ‘A’ 仍然是坏字符 , 这时候的匹配前缀缩短成了 “GTG” 。
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/15162949C-40.png)
文章插图
按照第一轮的思路 , 我们来重新确定最长可匹配后缀子串和最长可匹配前缀子串 。此时 , 剩下字符串 “G” 。
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516293192-41.png)
文章插图
第三轮 , 我们再次把模式串向后移动两位 , 让两个“G”对齐 , 继续从刚才主串的坏字符A开始进行比较 。
……
小结:整体思路是 , 在主串的好前缀中寻找最长可匹配后缀子串(在好前缀中 , 从后往前找) , 在模式串中寻找对应的最长可匹配前缀子串(在已匹配串中 , 从前往后找) , 直接把两者对齐 , 从而实现模式串的快速滑动 。
—— —— —— —— —— —— —— —— —— —— —— —— —— ——
- 知道了退回到哪里 , 现在的关键在于如何实现退回?【重难点】
经验总结扩展阅读
- 【前端必会】不知道webpack插件? webpack插件源码分析BannerPlugin
- 如何开展学习十八大,提高了教育的质量
- 十岁小孩学习不太好跟家长又不会怎么教他呢
- 20220929-ArrayList扩容机制源码分析
- 高效上课学习方法
- 怎么做一个学习的人
- Optional源码解析与实践
- Go 源码解读|如何用好 errors 库的 errors.Is 与 errors.As() 方法
- .Net下的分布式唯一ID
- .NET 反向代理 YARP 代理 GRPC
