本节知识点:
1.
KMP模式匹配算法,是为了避免普通字符串匹配算法中,没有必要的重复比较而设计的!在普通字符串比较中,通常有很多重复性的比较,KMP就是利用一个next数组当做索引,来避免这些重复性的比较!
2.对于具体算法的分析,本节不做过多叙述,详细可以参考<大话数据结构> 一书中的P135页。本节只做代码的保存!
示例代码:
/************************************************************************************
文件名:main.c
头文件:无
时间: 2013/03/31
作者: Hao
功能:KMP匹配算法的实现
难点:1.KMP算法的分析 才是真正的难点
************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/************************************************************************************
函数名: get_next
函数功能: 获得子串的next数组
参数: const char* str 字串数组 即要匹配的字符串 int* next 获得的next数组
返回值: 无
************************************************************************************/
void get_next(const char* str ,int* next)
{
int i, j;
i = 1;
j = 0;
next[1] = 0; //这个规定node数组是从第1个位置开始的且为0 第0个位置不用
while(i<strlen(str))
{
/*T[i]表示后缀的单个字符 T[j] 表示前缀的单个字符*/
if((0 == j) || (str[i-1] == str[j-1]))
{
++i;
++j;
if(str[i-1] != str[j-1])
{
next[i] = j;
}
else
{
next[i] = next[j];
}
}
else
{
j = next[j];
}
}
}
/************************************************************************************
函数名: Index_KMP
函数功能: 从主串Src到第pos位置开始 寻找子串str 出现的第一个位置
参数: const char* Src主串, const char* str子串, int pos重主串第pos位置开始寻找子串
返回值: 成功 返回子串在主串中的第一个位置
失败 即不存在匹配项 则返回-1
注意: pos是从0位置开始计算的 return的值是从1开始计算的
************************************************************************************/
int Index_KMP(const char* Src, const char* str, int pos)
{
int i = pos; //i永远是主串的下标 i永远不回溯
int j = 0; //j是子串的下标 j要根据next数组进行回溯
int next[100];
get_next(str ,next);
/*当i = strlen(Src) 说明主串遍历结束*/
/*当j = strlen(str) 说明子串匹配完成*/
while( (i < strlen(Src) ) && (j < strlen(str)) )
{
if((0 == j) || (Src[i-1] == str[j-1]))
{
++i;
++j;
}
else
{
j = next[j]; // 匹配失败 j进行回溯
}
}
if(j == strlen(str)) // 是子串匹配成功的情况 跳出的while循环
{
return i - j + 1;
}
else
{
return -1;
}
}
int main(int argc, char *argv[])
{
char* p = "ababaaaba";
char* s = "aab";
printf("%d\n",Index_KMP(p, s, 0));
printf("%d\n",Index_KMP(p, s, 5));
printf("%d\n",Index_KMP(p, s, 6));
return 0;
}
注意:对于KMP匹配算法,可以不一定完全理解next数组的算法,但一定要会使用next数组来对j变量进行回溯!!!达到查找的目的!!!