KMP算法C++实现

//参考资料 
//https://segmentfault.com/a/1190000004254889
//https://www.cnblogs.com/c-cloud/p/3224788.html
#include 
#include 
#include 
using namespace std;
class Solution
{
public:
    int matchString(const string &pat, const string &txt) 
    {
	//边界条件 
        // 1.模式串为空
        if (pat.empty())
        {
            return 0;
        }
        // 2.模式串的长度大于文本串的长度
        if (pat.size() >  txt.size())
        {
            return -1;
        }
        
        //计算next数组 
        vector next(p.size(), -1);
        calcNext(next, pat);
       
	//字符串匹配 
	//p是主人,t是客人
	//p回退   t不回退
        for (int p = 0, t = 0; t < txt.size(); t++)
        {
        // 第一步:获取p的值
		while (p > 0 && pat[p] != txt[t])
		{
			p = next[p-1];
		}
		if (pat[p] == txt[t])
		{
			p++;
		}
		// 第二步:判断模式串是否每个字符都匹配完成,并返回结果
        // 当完全匹配时,p是模式串的长度,t是文本串中与模式串的最后一个字符匹配的字符下标。
		if (p == pat.size())
		{
			return t-p+1;
		}
	}
        return -1;
    }
X  X  X  X  X  X  A  B  C  D  Y  Y  A    B   C   D
0  1   2   3  4  5  6   7  8   9  10 11 12 13 14  15                  
                          A  B  C  D
p = 4
t  = 9
t - p + 1 = 9 - 4 + 1 = 6
返回的是文本串中与模式串的第一个字符串匹配的字符下标。

    void calcNext(vector &next, const string &pat)
    {
	     //计算next数组
		//k回退,  p不回退
		//这就像机器学习中的训练集训练模型。自家人关着门训练。 
		next[0] = 0;
		for (int k = 0, p = 1; p < pat.size(); p++)
		{
            // 第一步:获取k的值
			while (k > 0 && pat[k] != pat[p])
			{
				k = next[k-1];
			}
			if (pat[k] == pat[p])
			{
				k++;
			}
            // 第二步:赋值给next数组
			next[p] = k;
		}
	}
};

int main(int argc, char* argv[])
{
	string txt = "XXXXABCDYYYYABCD";
	string pat = "ABCD";
	
	Solution s;
	cout << s.matchString(txt, pat) << endl;

	system("pause");
	return 0;
}

执行结果:
0 0 1 2 3 4 0
6

你可能感兴趣的:(数据结构和算法)