传统暴力求解匹配失败需要不停回溯主串,导致时间复杂度较高,而KMP算法不用回主串,只需要回溯子串,当匹配成功则返回子串在主串中的起始位置,否则返回空指针。
列如有以下两个串:
ABAABABBCBABABCA(主串)
ABABC(子串)
首先得算出每次子串能跳过几个字符,并放进next数组,next数组是通过推算共同的并且是最长的前后缀,匹配失败时应该找更小的前后缀防止有其他匹配成功的可能性。
完整代码如下
char* KMP(const char* dest, const char* scr)
{
int len = strlen(scr);//计算字串长度
int* next = (int*)malloc(static_cast<size_t>(len) * 4);//计算next数组所需要空间
//memset(next, 0, 12);
//int next[4] = { 0,1,0,1 };
int i = 1, j = 0;//数组下标和共同前后缀长度
next[0] = 0;//第一个始终为0
while (i < len)//计算next数组
{
if (!(scr[j] - scr[i]))//判断是否有相同的前后缀
{
j++;
next[i] = j;
i++;
}
else
{
if (!j)//没有更短的前后缀
{
next[i] = 0;//直接设为0
i++;
}
else
{
j = next[j - 1];//判断是否有更短的前后缀
}
}
}
//next[0] = 0, next[1] = 0, next[2] = 1, next[3] = 2,