暴力破解
当t="abcabcd",p="bcd"
时
i
t: a b c a b c d
s: b c d
j
不匹配进行下一位
i
t: a b c a b c d
s: b c d
j
匹配再进行下一位
i
t: a b c a b c d
s: b c d
j
i
t: a b c a b c d
s: b c d
j
不匹配
i
t: a b c a b c d
s: b c d
j
直到
i
t: a b c a b c d
s: b c d
j
匹配成功,返回i-j
若没有,则返回-1
// t 主串 p 模式串
int matching(char *t, char *p) {
int i, j;
i = j = 0;
//循环匹配结束条件是,i或j达到最大长度
while (t[i] != '\0' && p[j] != '\0') {
//相等,比较下一位,i++, j++
if (t[i] == p[j]) {
i++;
j++;
//不相等,回溯i和j
//j为0,i为下一位
} else {
i = i - j + 1;
j = 0;
}
}
//如果匹配到,则返回位置,若没有,则返回-1
if (p[j] == '\0') {
return i - j;
} else {
return -1;
}
}
KMP
KMP
算法的核心是创建next
数组
当t="abcabcabe",p="abcabe"
时
i
t: a b c a b c a b e
p: a b c a b e
j
。。。
i
t: a b c a b c a b e
p: a b c a b e
j
i
t: a b c a b c a b e
p: a b c a b e
j
前面有相同的,所以不需要比较前面的ab了
所以我们创建的next
数组就是存储每个j位置需要回溯的位置。
#define MAXSIZE 100
//获取next数组
int * getNext(char *p) {
int i = 0;
int k = -1
int nex[MAXSIZE];
//当位置为0时,不需要回溯,所以为-1
nex[0] = k;
while (p[i] != '\0') {
if (k == -1 || p[i] == p[k]) {
// 当两个字符相等时要跳过
if (p[++i] == p[++k]) {
nex[i] = nex[k];
} else {
nex[i] = k;
}
} else {
k = nex[k];
}
}
int *next = nex;
return next;
}
// t 主串 p 模式串
int KMPMatching(char *t, char *p) {
int i, j;
i = j = 0;
//获取next数组
int *next = getNext(p);
//循环匹配结束条件是,i或j达到最大长度
while (t[i] != '\0' && p[j] != '\0') {
//相等,比较下一位,i++, j++
if (t[i] == p[j]) {
i++;
j++;
//不相等,根据next数组回溯j
} else {
//i = i - j + 1;
//j = 0;
j = next[j];
}
}
//如果匹配到,则返回位置,若没有,则返回-1
if (p[j] != '\0') {
return i - j;
} else {
return -1;
}
}