1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
const int maxn = 1E5 + 10;
const int maxm = 1E4 + 10;
int next[maxm];
int kkk[maxn];
void makenext(char P[]){
//m p中的元素的数目
//next[i] 表示 P和P自己匹配,第i个位置,对应的匹配的前缀字符串的末端的位置
int m = strlen(P);
memset(next, 0 , sizeof(int)*m);
for
(int i = 1,j = 0;i < m;){
if
(P[i] == P[j]) next[i++] = ++j;
else
if
( j > 0) j = next[j - 1];
else
i++;
}
}
int kmp(char T[],char P[])
{
//T[] 需要进行匹配的数组
//P[] 需要完全匹配的数组
//n T中元素的数目
//m P中元素的数目
int n = strlen(T);
int m = strlen(P);
makenext(P);
int i = 0,j = 0;
//i表示当前匹配的位置
for
(;i < n;){
//根据需要,可以对条件i < n进行更改,或者直接在循环内加上判断跳出
if
(T[i] == P[j]) kkk[i++] = ++j;
//此时的j,表示P和T匹配,第i个位置,对应的匹配的前缀字符串的末端的位置
else
if
( j > 0 ) j = next[j - 1];
else
i++;
}
//对生成的kkk数组的相关结果进行相关处理和判断
return
-1;
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
const
int
maxm = 1E4 + 10;
int
next[maxm];
void
makenext(
char
P[]){
int
m =
strlen
(P);
memset
(next, 0 ,
sizeof
(
int
)*m);
for
(
int
i = 1,j = 0;i < m;){
if
(P[i] == P[j]) next[i++] = ++j;
else
if
( j > 0) j = next[j - 1];
else
i++;
}
}
int
kmp(
char
T[],
char
P[]){
int
n =
strlen
(T);
int
m =
strlen
(P);
makenext(P);
for
(
int
i = 0,j = 0;i < n;){
if
(T[i] == P[j]) i++,++j;
else
if
( j > 0 ) j = next[j - 1];
else
i++;
if
(j == m)
return
i - m;
}
return
-1;
}
int
mystrstr(
char
str[],
char
strsearch[]){
//在str中查找strsearch,
// 如果找到,返回第一次出现的下标,
// 否则返回-1
return
kmp(str,strsearch);
}
|
1
2
3
4
5
6
|
int
len =
strlen
(str);
makenext(str);
int
tmp = len - next[len - 1];
int
res;
if
(len % tmp || tmp == len) res = tmp - len % tmp;
//不是循环节,补成循环节需要的最少字符
else
res = 0;
//是循环节
|