kmp算法的c++实现

推荐先在B站搜索KMP看一个印度小哥讲解的视频:

首先简介kmp算法:

  KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。

实现的关键点:

  首先构造next辅助数组,假如说pattern串是aaba,那么pattern数组的内容便是{0, 1, 0, 1},这里面0代表从pattern头部到该位置的子字符串的没有公共前缀和后缀,1代表从pattern头部到该位置的子串的公共前缀和后缀的长度为1...。

 其次遍历主字符串,对于任意一位字符来说,

1. 如果该位字符和pattern位字符不相同,pattern串回溯,直到相同或者到达pattern串的头部。这时如果相同,主子符串和pattern串均前进一位。如果还不同,主字符串前进一位。

2. 如果该位字符和pattern位字符相同,pattern串和主子符串均前进一位,正常遍历。

代码如下:

// kmp算法.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include 
#include
#include
using namespace std;

vector getTempArray(string pattern)
{
	vector result;//声明要返回的vector
	if (pattern.size() == 0)
		return result;//如果字符串的长度为0,直接返回空的vector
	result.push_back(0);//首先在里面压入0
	if (pattern.size() == 1)//如果说字符串的长度为1,直接返回此时的vector
		return result;
	int i = 0;
	int j = 1;
	while (i <= pattern.size() - 1 && j <= pattern.size() - 1)
	{
		if (pattern[j] == pattern[i])
		{
			result.push_back(i + 1);
			i++;
			j++;
		}
		else
		{
			if (i == 0)
			{
				result.push_back(0);
				j++;
			}
			else
			{
				while (i >= 1&&pattern[i]!=pattern[j])
				{
					i = result[i - 1];
				}
				if (pattern[i] == pattern[j])
				{
					result.push_back(i + 1);
					i++;
					j++;
				}
				else
				{
					result.push_back(0);
					j++;
				}

			}
		}
	}
	return result;
}
int kmp(string t, string p)//t代表原字符串,p代表要匹配的字符串
{
	vector next = getTempArray(p);
	int j = 0;
	for (int i = 0; i < t.length(); i++)
	{
		while (j > 0 && t[i] != p[j])
			j = next[j - 1];
		if (t[i] == p[j])
			j++;
		if (j == p.length())
			return i - p.length() + 1;
	}
	return -1;
}
int main()
{
	string str;
	cout << "Enter the string: ";
	cin >> str;
	string pattern;
	cout << "Enter the pattern: ";
	cin >> pattern;
	int result = kmp(str, pattern);
	if (result == -1)
	{
		cout << "Not find pattern words!\n";
	}
	else
	{
		cout << result << endl;
	}
}

实现结果:

kmp算法的c++实现_第1张图片

你可能感兴趣的:(data,structure)