#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