您的位置:首页 > 其它

字符串模式匹配KMP算法

2010-05-24 23:07 387 查看
最近在重新学习数据结构,字符串KMP算法的实现写了下,一同分享。

// 失配函数
// pat           模式字符串
// patLength     字符串长度
// failResult    失配位置数组(长度为patLength)
void Mismatch(const char *pat, int patLength, int *failResult)
{
	// 第一个位置失配值为-1
	failResult[0] = -1;

	// 用于记录前一个失配值
	int preFailVal = 0;
	for (int j=1; j<patLength; j++)
	{
		// 得到前一个位置失配值
		preFailVal = failResult[j-1];

		// 若比较字符不等则继续向前比较失配位置的字符,直到相等或不存在失配值的位置停止
		while (pat[j]!=pat[preFailVal+1] && preFailVal>=0)
		{
			preFailVal = failResult[preFailVal];
		}

		// 若相等则当前失配值为前一个失配值+1
		if (pat[j] == pat[preFailVal+1])
		{
			failResult[j] = preFailVal + 1;
		}
		// 不相等则为-1
		else
		{
			failResult[j] = -1;
		}
	}
}

// KMP模式匹配算法
// string       字符串
// pat          待查找模式
// 成功返回模式首字母出现的位置,失败返回-1
int KMPMatch(const char *string, const char *pat)
{
	// 参数有效性
	if (string==NULL || pat==NULL)
	{
		return -1;
	}

	// 计算字符串长度
	int lenString = strlen(string);
	int lenPat = strlen(pat);

	// 比较长度
	if (lenPat > lenString)
	{
		return -1;
	}

	// 分配失配值数组
	int *pFailArray = new int[lenPat];
	if (pFailArray == NULL)
	{
		return -1;
	}

	// 初始化失配值数组
	for (int k=0; k<lenPat; k++)
	{
		pFailArray[k] = -1;
	}

	// 计算失配值
	Mismatch(pat, lenPat, pFailArray);

	// 进行模式匹配
	int nFindPos = -1;
	int i=0;
	int j=0;
	while (i<lenString && j<lenPat)
	{
		// 字符相等
		if (string[i] == pat[j])
		{
			i++;
			j++;
		}
		// 发生失配
		else
		{
			if (j == 0)
			{
                i++;
			}
			else
			{
				j = pFailArray[j-1] + 1;
			}
		}

		nFindPos = (j==lenPat) ? (i-lenPat) : -1;
	}

	// 释放失配值数组空间
	if (pFailArray != NULL)
	{
		delete[] pFailArray;
		pFailArray = NULL;
	}

	// 返回查找结果
	return nFindPos;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: