kmp算法是由三位大神容忍不了普通字符串查找方法的时间效率达到了O(n*m),因而发明的算法。它让字符串的查找达到了O(n+m)。我们可以先看看普通方法解决这个问题,为了让大家更加理解题目,我把题目的意思再表达得更清楚。
题目:我们设字符串的主串名为str,字符串的子串名为sub,我们现在想要在主串str中查找是否存在子串sub。
一、朴素查找算法
思想:我们利用两个下标i和j,i为主串的下标,j为子串的下标,如果相同两个下标对应的元素相同,则继续往下走,如果走到某个位置两个下标对应的元素不同了,那就需要回退,这里需要注意,j回退到子串的0号下标位,i也需要回退,因为刚刚我们搜索失败只是我们以i-j开头的字符串和子串不匹配,我们还可以i-j+1下标的字符开头查找,也许就匹配了呢!回退是防止漏了可能匹配的答案。好吧,文字可能太枯燥难懂,那我们就看图吧。
第一步:两个字符串初始化定位,i和j都在0号下标。
第二步:i和j对应的下标相同,则i下标和j下标都可以往后走。
第三步:i和j对应的下标不同了就说明匹配失败了,那我们就需要回退,在原来开始字符下标位置向后走一位,这个位置我们是怎么求出来的呢,我们可以看看上面的图,当i和j匹配事变的时候,i其实就走了j步,j每次都从零开始,i和j又是同时走的,所以它两走的步数一致,用i-j我们就回到了这个字符串匹配的开始位置,再+1就是原来位置的下一个字符了,也就是我们检测匹配的新的位置。
第四步:如果我们找到了返回什么呢?上面第三步已经解释清楚了,我们就是返回i-j就可以了。
代码实现:
//在str的pos位置开始查找子串sub
//缺点:i一定要回退
//优点:简单
int BF(const char *str,const char *sub,int pos)//O(n*m)
{
if(pos < 0)
{
return -1;
}
int lenstr = strlen(s