![](https://images2018.cnblogs.com/blog/1287367/201807/1287367-20180717222007249-2085991914.jpg)
1.kmp
#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
",Index_KMP(strF,strS,0));
return 0;
}
x
100
1
2
3
4
5
6
7
8
void get_nextval(char *str,int *nextval)
9
{
10
int i,j;
11
i = 0;
12
j = -1;
13
nextval[0] = -1;
14
15
16
int len = strlen(str);
17
while(i < len)
18
{
19
if(j==-1 || str[j]==str[i])//str[i]表示后缀的单个字符,str[j]表示前缀的单个字符
20
{
21
++i;
22
++j;
23
if(str[i] != str[j]) //若当前字符与前缀字符不同,则当前的j为nextvale在i位置的值
24
{
25
nextval[i] = j;
26
}
27
else //否则将前缀字符的nextval值赋给后缀字符的nextval
28
{
29
nextval[i] = nextval[j];
30
}
31
}
32
else
33
{
34
j = nextval[j];//若字符不同,则j值回溯
35
}
36
}
37
}
38
39
40
void get_next(char *str,int *next)
41
{
42
int i,j;
43
i = 0;
44
j = -1;
45
next[0] = -1;
46
47
int len = strlen(str);
48
while(i < len)
49
{
50
if(j==-1 || str[i]==str[j])
51
{
52
++i;
53
++j;
54
next[i] = j;
55
}
56
else
57
{
58
j = next[j];
59
}
60
}
61
}
62
63
64
65
int Index_KMP(char *strF,char *strS,int pos)
66
{
67
int i = pos;
68
69
int j = 0;//字串中当前位置下标值
70
int next[255];
71
get_nextval(strS,next);
72
73
int lenF = strlen(strF);
74
int lenS = strlen(strS);
75
while(i < lenF && j < lenS) //若i小于lenF且j小于lenS,循环继续
76
{
77
if(j == -1 || strF[i]==strS[j])//两字符相等或者j为-1则继续
78
{
79
++i;
80
++j;
81
}
82
else
83
{
84
j = next[j];//j回退合适的位置,i不变
85
}
86
}
87
88
if(j >= lenS)return i-lenS;//必须要由j使循环退出才说明找到了这个子串的位置
89
else return 0;
90
}
91
92
93
94
int main()
95
{
96
char *strF = "abcdecdefg";
97
char *strS = "defg";
98
printf("%d
",Index_KMP(strF,strS,0));
99
return 0;
100
}