统计字符流中一个字符串出现的次数- KMP算法

这是google onsite的一个题目, 说是一个无限的0/1字符串流, 给定一个字符串如”110010″, 求到当前为止, 在字符流中出现了多少次这种字符.

一开始想到dp来做, 然后画了一下转移方程感觉不对, 然后又感觉越看越像是KMP, 仔细分析可以发现, 其思路就是求当前字符流的后缀与给定的字符串相等即可. 按照正常的思路即取与给定字符串长度相等的字符串, 比较是否相等即可, 这种方式的时间复杂为O(mn), 其中m为给定字符串, n长度为字符流长度. 利用KMP可以优化至O(n).

关于KMP, 我也不想仔细多说, 因为要说清楚很麻烦. 其主要思路是先对pattern字符串求每一位后缀与前缀的匹配长度, 然后在pattern[k]与str[i]进行匹配的时候, 如果当前一位不相等, 那么pattern字符串回退到与pattern[i-1]位后缀相等的前缀的后一位(看不懂就算了). 

代码如下:

class Solution {
public:
    int getNext(vector<int>& next, string& str)
    {
        int len = str.size(), k = 0;
        for(int i = 1; i < len; i++)
        {
            while(k>0 && str[i]!= str[k]) k = next[k-1];
            next[i] = (k+=str[i]== str[k]);
        }
        return next[len-1];
    }
    
    int match(string& str, string& pattern, vector<int>& next)
    {
        int ans = 0, len1 = str.size(), len2 = pattern.size(), k =0;
        for(int i = 0; i < len1; i++)
        {
            while(k > 0 &&str[i] != pattern[k]) k = next[k-1];
            k += (str[i] == pattern[k]);
            if(k == len2) ans++;
        }
        return ans;
    }
    
    int count() {
        string str = "11001100110011111", pattern = "1100";
        vector<int> next(pattern.size(), 0);
        getNext(next, pattern);
        return match(str, pattern, next);
    }
};
    原文作者:KMP算法
    原文地址: https://blog.csdn.net/qq508618087/article/details/52343499
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞