KMP算法

一. 最简单的字符串匹配

记录两初始指针从前往后移动,匹配成功则一起后移
匹配失败则模板串指针回到首位,被匹配串指针移到上一次上一次初始匹配的下一位置
直至模板串匹配完返回真,或者被匹配串匹配完返回假,时间复杂度为O(mn)

class Solution {
public:
    int strStr(string haystack, string needle) {
        if(needle.size()==0) return 0;//空串
        int i =0, j =0;//因为还会用到,所以不能在循环中定义
        while(i<haystack.size()&&j<needle.size()){
            if(haystack[i]==needle[j]){i++;j++;}//单字符匹配成功一起后移
            else{i=i-j+1;j=0;}//模板串指针重置,匹配串指针移动到上次开始匹配的下一位置
            //注意这里得先重置i指针,即被匹配串指针,否则会失去移动距离的信息
        }
        //匹配结束
        if(j==needle.size()) return i-j;
        return -1;//匹配失败
    }
};

二. KMP算法

C++做题模板

vector<int> fail(len, -1);//初始无前一元素,跳转-1,同时表示无相等元素,因为后面还要增
for (int i = 1; i < len; i++){//从1开始,评估每个位置应跳转的地方
    int j = fail[i - 1];//前一元素的跳转位置
    while (j != -1 && evil[j + 1] != evil[i]) //跳转后的后一元素继续比较当前元素
        j = fail[j];//,匹配失效,继续跳转,压缩转移位置
    if (evil[i] == evil[j + 1])   fail[i] = j + 1;//相等记录该位置
    //否则跳转到-1
}

暴力匹配的优化,实际上改进了匹配失效后,主串指针回溯的距离,减少遍历次数
核心是对模板串进行评估,记录匹配任意一位匹配失效需要回溯的距离(位置),空间换时间
时间复杂度为O(m+n),使算法性能成线性
具体方法是利用模板串本身结构特点,使得已遍历的信息不用再次确认,即用这种结构记录了已遍历信息

三. 实例

1. 最短回文串

2. 找到所有好字符串

posted @ 2022-06-02 16:06  失控D大白兔  阅读(36)  评论(0编辑  收藏  举报