BF
int BF(char* s, char* t) {
int i = 0, j = 0;
int n = strlen(s), m = strlen(t);
while (i < n && j < m) {
if (s[i] == t[j]) {
i++;
j++;
}
else {
i = i - j + 1;
j = 0;
}
}
if (j >= m) {
return i - j;
}
else {
return -1;
}
}
KMP
考察KMP的next数组或nextval数组,KMP匹配过程
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
void getNextval1(char *t, int* next, int* nextval) {
nextval[0] = -1;
int m = strlen(t);
for (int i = 1; i < m; i++) {
if (next[i] != -1 && t[i] == t[next[i]]){
nextval[i] = nextval[next[i]];
}
else {
nextval[i] = next[i];
}
}
}
void getNextval(char* t, int* nextval) {
int i = 0, j = -1;
int m = strlen(t);
nextval[0] = -1;
while (i < m) {
if (j == -1 || t[i] == t[j]) {
i++;
j++;
if (t[i] != t[j])
nextval[i] = j;
else
nextval[i] = nextval[j];
}
else {
j = nextval[j];
}
}
}
void getNext(char* t, int* next) {
int i = 0, j = -1;
next[0] = -1;
int m = strlen(t);
while (i < m) {
if (j == -1 || t[i] == t[j]) {
j++;
i++;
next[i] = j;
}
else {
j = next[j];
}
}
}
int KMP(char *s, char *t) {
int i = 0, j = 0;
int n = strlen(s), m = strlen(t);
int* next = (int*)malloc(sizeof(int) * (m+1));
getNextval(t, next);
while (i < n && j < m) {
if (j == -1 || s[i] == t[j]) {
i++;
j++;
}
else {
j = next[j];
}
}
if (j >= m) {
return i-j;
}
else {
return -1;
}
}
int main() {
char s[30] = "aaaaaab";
char t[10] = "aaaab";
int k = KMP(s, t);
printf("%d", k);
}
- 设有两个串S和S2,求S2在S1中首次出现的位置的运算称为( 模式匹配)。
- 设主串的长度为n,子串的长度为m,则简单的模式匹配算法的时间复杂度
为(O(n*m) ), KMP算法的时间复杂度为( O(m+n))。 - 如何手算next数组和next数组
首先:计算每一个字母以前的字符串的最长前后缀
其次:右移一位,首位填-1,求得next数组
最后:判断当前字符x和当前字符next数组值对应位置的字符y是否相等,相等当前字符nextval=字符y的nextval,否则当前字符nextval=当前字符next
.ababaaababaa
.001231123456(最长前后缀)
-100123112345(next数组)
-10-10-1310-10-13(nextval数组)
提升
编程实现:模式串在主串中有多少个完全匹配的子串?
int fun(char* s, char* t) {
int i = 0, j = 0, k = 0;
int n = strlen(s), m = strlen(t);
int* next = (int*)malloc(sizeof(int) * (m + 1));
getNext(t, next);
while (i < n) {
if (j == -1 || s[i] == t[j]) {
if (j + 1 == m) {
j = next[j];
k++;
continue;
}
i++;
j++;
}
else {
j = next[j];
}
}
//printf("%d\n", k);
return k;
}