KMP算法(串的匹配)- C语言

KMP
采用部分匹配方式,每次扫描主串不必回溯,整个过程只扫描主串一遍,算法复杂度大大降低。

算法复杂度:O(n+m)

由于主串不必回溯,所以在匹配数据量大的文件使,不必放入缓存,可以边读取边进行模式匹配。

代码如下:

//Authors:xiaobei

#include<stdio.h> 
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 100
#define OK 1
#define ERROR 0
typedef struct
{
 char ch[MAXSIZE+1];
 int length;
}SString;     //定义串结构体
int Index_KMP(SString S,SString T,int pos,int nextval[]);
void get_nextval(SString T,int nextval[]);  //get_next函数获得next[]数组
int main()
{
 printf("这里是KMP算法!
");
 int nextval[] = {0};     //定义next[]数组
 int pos = 1,pos_i;
 SString S,T;
 printf("
请输入主串)>>>");     //输入主串,并获得主串长度,输出主串
 gets(S.ch);
 S.length = strlen(S.ch);
 printf("
len_S:%d
",S.length);
 puts(S.ch);
 printf("
请输入要匹配子串)>>>");   //输入子串,并获得子串长度,输出子串
 gets(T.ch);
 T.length = strlen(T.ch);
 printf("
len_T:%d
",T.length);
 puts(T.ch);
 get_nextval(T,nextval);      //获得next
 pos_i = Index_KMP(S,T,pos,nextval);   //调用函数获得第一次匹配成功位置pos_i
 printf("
匹配的起始位置为:%d",pos_i);
 return 0;
}
int Index_KMP(SString S,SString T,int pos,int nextval[])  //串检索匹配函数
{
 int i,j;
 i = pos;
 j = 1;
 while(i<=S.length && j<=T.length)       //当检索位置同时小于主串与子串时,执行循环
 {
  if(j == 0 || S.ch[i-1] == T.ch[j-1])
  {
   i++;
   j++;
  }
  else
   j = nextval[j];
 }
 if(j>T.length)
  return i-T.length;          //匹配成功 
 else
  return 0;            //匹配失败 
}
//获得next[]数组的函数
void get_nextval(SString T,int nextval[])
{
 int i,j;
 i = 1;
 nextval[1] = 0;
 j = 0;
 while(i<T.length)
 {
  if(j == 0 || T.ch[i] == T.ch[j])
  {
   i++;
   j++;
   if((T.ch[i]!=T.ch[j]))
    nextval[i] = j;
   else
    nextval[i] = nextval[j];
  }
  else
   j = nextval[j];
 }
 printf("--------------------
");
 printf("输出next数组:
");
 for(i = 0;i<T.length;i++)
  printf("%d ",nextval[i]);
 printf("
--------------------");
}

运行结果:

KMP
运行环境:
Dev-C++

原文地址:https://www.cnblogs.com/slz99/p/12527740.html