【ADT】串_KMP算法

        今天一天学习了kmp算法,原以为一上午就能搞定的事情结果一天了还没弄好,还差对于具体代码实现自己还没有敲,本着不能一知半解为自己的知识和事业学习的原则,便听了王道,天勤,代码随想Carl,木子喵neko四个老师对于kmp不同角度的算法的理解,写这篇文章对于一天的学习进行一个总结,如下:

        1.问题引入:如何能够快速在一个主串中进行与模式串完全相同的字符串内容的查找?

        2.解体思路:由暴力算法的双层循环的外循环的角度出发,发现暴力算法之所以时间复杂度= O(nm)如此之高,(n表示主串长度,m表示模式串长度,防止下面思维混乱主串叫A串模式串叫B串(木子老师的叫法)),刚才说暴力算法复杂度为什么那么高,木子老师说的很好:是由于暴力算法没有从每次配对中吸取经验教训,而KMP算法的核心就是:利用匹配失败后的信息,尽量减少模式串与主串的匹配次数,以达到快速匹配的目的。那这里匹配失败后的信息是指什么呢?是指:模式串当前匹配失败的元素之前的所有元素都与主串对应位置的元素完全相同,我们利用这个隐藏信息将当前的i指针不回溯,只将j回溯到指定位置(i是主串匹配元素下标,j为模式串匹配元素的下标)这样就能减少时间复杂度,那么问题又来了什么叫做指定位置?怎么样回溯到指定位置?这就要引出字符串的前后缀、公共前后缀、最大公共前后缀、仅仅对三个概念理解了还不够,因为你仅仅会找一个字符串的最大公共前后缀,而不是去从抽象的字符串与下标指针的关系上解决这个快速移动的问题。

        3.关于以上1)字符串的前后缀、公共前后缀、最大公共前后缀、三个概念去木子老师从集合的角度说的很好可以去b站搜索木子喵neko听一下。2)关于如何找最大公共前后缀我认为B站代码随想carl 把我讲明白了。

        4.而对这里的找到最大公共前后缀后为什么能够快速移动,这里我想到一种数学思想,就是替换或者说整体法,这是我们高中做函数题求函数解析式用的,我们这里把两个相同的子串理解为相同的字符块,类似T = (某一个解析式),这样我们就可以一次比较相同的字符块来替代逐次比较。这是一个动态的过程这个过程天勤演示的很形象!并且有两点需要注意:1)

        5.关于模式串每次回溯重新开始的位置:其实这个要配合对于串这个概念的下表为0的元素是否存放数据以及最大公共元素位j对应的next[j]的值的计算方法来判断。EX1:比如Carl的1)下标0的元素存放了数据且 2)下标j对应的next[j]是该j对应下标位置包括该下表对应元素以及之前的元素对应的模式串中的元素组成的子串含有的最大公共前后缀,那么他就直接看发生冲突元素的前一位next数组对应的值,就是新的一轮配对的j下标的位置。EX2:比如王道的他是下标为0不存放元素,且(下标j对应的next[j]是该j对应下标位置包括该下表对应元素以及之前的元素对应的模式串中的元素组成的子串含有的最大公共前后缀)+1 ⇔(karl的下标j与对应next[j])+1,所以王道其实相当于先将所有元素的下标都后移也就是第一个元素对应下标1而不是karl的0,然后将next[j]数组对应的值也一同+1这样相当于平移了数组元素与回溯的下标,也就是没有什么变化。不过这里要注意的是:我们要看发生冲突元素前一位next[j]对应的值,这个值也就是回溯对比指向的下标的新的位置。

        6.其实还有很多点要注意,比如:j与next[j]的关系,最后一个next[j]要注意是子串不能是模式串全体,以及找最大前后缀的时候相等时前缀后缀同样都是从左往右的顺序一样的前提下才一样,一定要注意是一样的顺序,还有就是点那个next[j] == 0 时,要进行i++和j++ 也即主串与模式串的第一个都不想等,都要两个下标指针都要同时往后移一个进行新的比较。

以上今日毕

明日继续努力!

 

  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值