1.在牛客网上遇到的KMP算法

题目描述

给你一个字符串ST
计算ST出现了多少次?
数据范围:1<=len(S)<=5∗1e5,1<=len(T)<=1e6
复杂度要求:O(m*n)

示例1

输入:"ababab","abababab"
输出: 2

示例12

输入:"abab","abacabab"
输出: 1


C++解答

思路

这题跟leetcode上一条str比较相似,不同的是:ST中可能出现多次,因此需要每次匹配出结果后,需要对数组进行一次回退,其余跟str一致。

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 计算模板串S在文本串T中出现了多少次
     * @param S string字符串 模板串
     * @param T string字符串 文本串
     * @return int整型
     */
    vector<int> next_arr(string& str){
        int n = str.size();
        vector<int> next(n, 0);
        int j = 0;
        for(int i = 1; i < n; i++){
            while(j > 0 && str[i] != str[j]){
                j = next[j - 1];
            }
            if(str[i] == str[j])
                j++;
            next[i] = j;
        }
        return next;
    }
    int kmp(string S, string T) {
        // write code here
        int m = S.size(), n = T.size();
        if(m > n) return 0;
        int count = 0;
        vector<int> next = next_arr(S);
        int j = 0;
        for(int i = 0; i < n; i++){
            while(j > 0 && S[j] != T[i]){
                j = next[j - 1];
            }
            if(S[j] == T[i])
                j++;
            //匹配到m时选择回退还是跳出循环,必须是j == m,因为上次匹配的是j - 1
            if(j == m){
                //如果P也到头了,跳出循环
                if(i == n - 1){
                    count++;
                    break;
                }
                j = next[j - 1];
                count++;
            }
        }
        return count;
    }
};
posted @ 2021-08-22 17:26  什么名字比较好  阅读(46)  评论(0)    收藏  举报