依旧来举例说明:
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516293153-67.png)
文章插图
将已经匹配的 “BC” 称为好后缀 , 记作 { u } 。我们用它在模式串中寻找另一个与好后缀匹配的字符串 { u* } 。
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/15162a5a-68.png)
文章插图
如果存在 , 则将模式串滑动到子串 { u* } 与好后缀 { u } 上下对齐的位置 。
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516294057-69.png)
文章插图
如果不存在 , 则直接滑动到好后缀 { u } 的后面 。
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516295603-70.png)
文章插图
此外 , 若在模式串中若存在多个与好后缀匹配的相同字符串或与好后缀的后缀字串相同的模式串中的前缀子串 , 则选择最长且靠后的串并记为 { v } , 按规则滑动 。
以上就是BM算法的两个核心规则 , 在使用中可以分别计算好使用两用规则的滑动位数 , 取较大的一个 max( k1, k2 ) , 作为向后滑动的位数 , 这样既能使得时间复杂度接近最优的O( n / m ) , 也能避免滑动位数出现负数的情况 。
具体实现如下:
(1)对于坏字符规则的计算 , 如果每次都去遍历那效率会很低 , 可以利用一个哈希表 , 存储每个字符在模式串中的位置 , 如果有多个相同字符 , 则取下标最大的一个 。如图:
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516292A9-71.png)
文章插图
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516294032-72.png)
文章插图
(2)对于好后缀规则 , 其核心在于:在模式串中查找与好后缀匹配的子串;在好后缀的所有后缀字串中 , 查找能与模式串前缀子串匹配的最长子串 。
- 先来解决第一个问题 , 如何表示模式串中不同的后缀字串以及如何滑动到对应位置?
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516295951-73.png)
文章插图
如果存在多个合法的子串 , 则取下标最大的一个 。
—— —— —— —— —— —— —— —— —— —— —— —— —— ——
- 找完了模式串中的所有子串 , 还有一个问题:查找在好后缀的所有后缀子串中 , 能与模式串前缀子串匹配的最长的一个后缀子串(以下记为 “最长可匹配后缀子串”)
![.NET源码学习 [算法2-数组与字符串的查找与匹配]](http://shimg.jingyanzongjie.com/230724/1516293260-74.png)
文章插图
—— —— —— —— —— —— —— —— —— —— —— —— —— ——
- 接下来 , 理解并推导一下这两个数组的值
经验总结扩展阅读
- 【前端必会】不知道webpack插件? webpack插件源码分析BannerPlugin
- 如何开展学习十八大,提高了教育的质量
- 十岁小孩学习不太好跟家长又不会怎么教他呢
- 20220929-ArrayList扩容机制源码分析
- 高效上课学习方法
- 怎么做一个学习的人
- Optional源码解析与实践
- Go 源码解读|如何用好 errors 库的 errors.Is 与 errors.As() 方法
- .Net下的分布式唯一ID
- .NET 反向代理 YARP 代理 GRPC
