KMP解释:从主串中查找子串,返回子串在主串中的位置。
eg:主串"adadacacbc",子串 "adac" ->2
代码解析:
(1)在主串中查找子串:
循环遍历,对主串和子串的字母逐个匹配:arr[i]-'0'得到当前下标的字母。
(2)如果前几个字母匹配,并不是完全匹配,如何继续查找:
如:主串"adadacacbc",子串 "adac",匹配前3个字母时一致,后面不匹配,但是直接从后面继续查找就不可能匹配成功了,必须返回前面查找,返回的位置是:当前主串下标-当前子串下标+1:i-j+1。
(3)终止循环的条件:
匹配成功:匹配到了子串的最后一个位置: brr[j] == ' ';
匹配不成功:查找主串到最后一个位置也没找到:arr[i] == ' '
终止条件: brr[i] == ' ' &&arr[i] == ' ',必须要同时满足,因为如果只满足了一个,当子串已经被完全匹配了,而母串没到最后一个位置,就要进入死循环了。
也可以定义一个计数器count,每当匹配成功时count++,不成功置为0,如果count==子串长度退出循环。
完整代码:
int KMP(char* arr,int len,char* brr,int length)
{
//这个思想错误,没有考虑到每次重新匹配时count都要置为0
int j=0, i=0;
while(arr[i] != ' '&& brr[j] != ' ')
//两个条件应该是同时满足的
{
if (arr[i] == brr[j])
{
i++, j++;
}
else {
i++;
i = i - j + 1;
j = 0;
}
}
return brr[j]==' '?i - j:-1;
}
int main()
{
char arr[] = "adadacacbc";
char brr[] = "adac";
int len = strlen(arr);
int length = strlen(brr);
printf("%d",KMP(arr, len, brr, length));
return 0;
}
运行结果:



