(七)《数据结构与算法》 青岛大学-王卓 串

串 可以理解为内容受限的线性表
主要讲解两个算法,一个是BF算法,朴素的模式匹配法(亦称暴力破解法);另一个是KMP算法,这个算法是三位前辈创的,避免了重复遍历的情况。另外是在KMP算法的基础上进行的优化,只需改动内置函数next()。

/*
	BF算法:也称暴力破解法,通过穷举法的思路进行比对。
	可以理解为双指针。 时间复杂度O(n*m)
	KMP算法:通过next数组记录 模式串 的重复部分,从而将时间复杂度提高 O(n+m);
*/

#include
using namespace std;

int BF_Index(string S, string T, int pos)
{
	int i = pos;
	int j = 0;
	int slen = S.size();
	int tlen = T.size();
	while (i<slen && j< tlen)
	{
		if (S[i] == T[j])	// 主串和子串匹配则继续下一个字符
		{
			i++;
			j++;
		}
		else				// 不匹配则主串回溯到开始前的下一个字符,且子串重新开始
		{
			i = i - j + 1;
			j = 0;
		}
	}
	if (j >= tlen) return i - tlen;		// j等于tlen说明子串遍历了所有字符都与主串相同,下标返回为 主串此时的下标 - 子串的长度
	else return 0;							// 否则说明,主串遍历所有,也没有相同的
}

void Get_Next(string T,int *next)
{
	int i=0,j=-1;
	int tlen = T.size();
	next[0] = -1;
	while (i < tlen)
	{
		if (j==-1 || T[i] == T[j])
		{
			++i;
			++j;
			next[i] = j;
		}
		else j = next[j];	// 若字符不相等,则j值回溯
	}
}

void Get_Nextval(string T, int* next)
{
	int i = 0, j = -1;
	int tlen = T.size();
	next[0] = -1;
	while (i < tlen)
	{
		if (j == -1 || T[i] == T[j])
		{
			++i;
			++j;
			if (T[i] != T[j]) next[i] = j;
			else next[i] = next[j];		
		}
		else j = next[j];	// 若字符不相等,则j值回溯
	}
}

int KMP_index(string S, string T, int pos)
{
	int i = pos;
	int j = 0;
	int slen = S.size();
	int tlen = T.size();
	int next[255];
	Get_Nextval(T, next);
	while (i < slen && j < tlen)
	{
		if (S[i] == T[j])	// 主串和子串匹配则继续下一个字符
		{
			i++;
			j++;
		}
		else				// 不匹配
		{
			j = next[j];
		}
	}
	if (j >= tlen - 1) return i - tlen;		
	else return 0;							
}



int main()
{
	string s = "00000000001";
	string t = "00001";
	int index = BF_Index(s, t, 0);
	cout << "BF算法:" << index << endl;
	index = KMP_index(s, t, 0);
	cout << "KMP算法:" << index << endl;
	return 0;
}

你可能感兴趣的:(数据结构与算法,算法,c++)