
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
void get_nextval(char *str,int *nextval)
{
int i,j;
i = 0;
j = -1;
nextval[0] = -1;
int len = strlen(str);
while(i < len)
{
if(j==-1 || str[j]==str[i])//str[i]表示后缀的单个字符,str[j]表示前缀的单个字符
{
++i;
++j;
if(str[i] != str[j]) //若当前字符与前缀字符不同,则当前的j为nextvale在i位置的值
{
nextval[i] = j;
}
else //否则将前缀字符的nextval值赋给后缀字符的nextval
{
nextval[i] = nextval[j];
}
}
else
{
j = nextval[j];//若字符不同,则j值回溯
}
}
}
void get_next(char *str,int *next)
{
int i,j;
i = 0;
j = -1;
next[0] = -1;
int len = strlen(str);
while(i < len)
{
if(j==-1 || str[i]==str[j])
{
++i;
++j;
next[i] = j;
}
else
{
j = next[j];
}
}
}
int Index_KMP(char *strF,char *strS,int pos)
{
int i = pos;
int j = 0;//字串中当前位置下标值
int next[255];
get_nextval(strS,next);
int lenF = strlen(strF);
int lenS = strlen(strS);
while(i < lenF && j < lenS) //若i小于lenF且j小于lenS,循环继续
{
if(j == -1 || strF[i]==strS[j])//两字符相等或者j为-1则继续
{
++i;
++j;
}
else
{
j = next[j];//j回退合适的位置,i不变
}
}
if(j >= lenS)return i-lenS;//必须要由j使循环退出才说明找到了这个子串的位置
else return 0;
}
int main()
{
char *strF = "abcdecdefg";
char *strS = "defg";
printf("%d \n",Index_KMP(strF,strS,0));
return 0;
}void get_nextval(char *str,int *nextval){ int i,j; i = 0; j = -1; nextval[0] = -1; int len = strlen(str); while(i < len) { if(j==-1 || str[j]==str[i])//str[i]表示后缀的单个字符,str[j]表示前缀的单个字符 { ++i; ++j; if(str[i] != str[j]) //若当前字符与前缀字符不同,则当前的j为nextvale在i位置的值 { nextval[i] = j; } else //否则将前缀字符的nextval值赋给后缀字符的nextval { nextval[i] = nextval[j]; } } else { j = nextval[j];//若字符不同,则j值回溯 } }}void get_next(char *str,int *next){ int i,j; i = 0; j = -1; next[0] = -1; int len = strlen(str); while(i < len) { if(j==-1 || str[i]==str[j]) { ++i; ++j; next[i] = j; } else { j = next[j]; } }}int Index_KMP(char *strF,char *strS,int pos){ int i = pos; int j = 0;//字串中当前位置下标值 int next[255]; get_nextval(strS,next); int lenF = strlen(strF); int lenS = strlen(strS); while(i < lenF && j < lenS) //若i小于lenF且j小于lenS,循环继续 { if(j == -1 || strF[i]==strS[j])//两字符相等或者j为-1则继续 { ++i; ++j; } else { j = next[j];//j回退合适的位置,i不变 } } if(j >= lenS)return i-lenS;//必须要由j使循环退出才说明找到了这个子串的位置 else return 0;}int main(){ char *strF = "abcdecdefg"; char *strS = "defg"; printf("%d \n",Index_KMP(strF,strS,0)); return 0;}
原文:https://www.cnblogs.com/LyndonMario/p/9326345.html