总结:
1.KMP算法和BF算法很相似,区别在于KMP算法的主串 i 值不用回溯,匹配到哪就是哪,模式串的 j 值不是回到 1 ;而是回到 next[ j ].
2.next[ j ]数组是什么呢?
3.next 函数还是不太会,需要后续有时间加强学习!!!
#include<stdio.h>
#include<stdlib.h>
#include<stdio.h>
#include<stdlib.h>
#define MAXLEN 255
#define OK 1
#define ERROR 0
#define OVERFLOW -2
int i, n, j, x;
char e;
int next[255];
//顺序存储串
typedef struct {
char ch[MAXLEN + 1];//存储串的一维数组 ch[0]闲置不用,从[1]开始到[255]来存放字符。
int length;//串当前长度
}SString;
//串赋值
int StringAssign(SString& S, char chs[]) {//生成一个其值等于字符串常量chs的串S
int i = 0;
while (chs[i] != '\0') {//循环,将字符串常量的值赋值给S
S.ch[i + 1] = chs[i];//S.ch数组从下标为1开始存放
++i;
}
S.length = i;//将i赋值给S的长度
return 0;
}
//BF算法
int Index_BF(SString& S, SString& T, int pos) {
//S是主串,T是模式串,pos是主串开始匹配的位置
int i = pos; int j = 1;
while (i <= S.length && j <= T.length) {
//循环结束条件就是要么主串没有和模式串匹配的那一段,
//要么就是匹配成功,j到了模式串最后一位的下一位置
if (S.ch[i] == T.ch[j]) {
i++;
j++;
}
else {
i = i - j + 2;//可以理解为i= (i-j+1)+1,(要先知道,
// 串里面的数组下标为0的地方是不放元素的,所以i是从1开始算起的)
//意思就是主串的i回到出发的位置,然后要让i+1,
// 就是让i从开始的位置的下一个位置开始往后匹配。
j = 1;//让j回到第一个位置
}
}
if (j > T.length) {//匹配成功
printf("\n匹配成功!");
printf("\n模式串匹配成功的位置为%d.", i - T.length);
return OK;//返回的就是模式串的第一个元素的下标(也是位置),
//因为数组第一位不存元素,所以下标等于位置
}
else {
printf("\n匹配不成功!");
return ERROR;
}
}
//KMP算法
int Index_KMP(SString& S, SString& T, int pos) {
//S是主串,T是模式串,pos是主串开始匹配的位置
int i = pos; int j = 1;
while (i <= S.length && j <= T.length) {//循环结束条件就是要么主串没有和模式串匹配的那一段,
//要么就是匹配成功,j到了模式串最后一位的下一位置
if (j==0 || S.ch[i] == T.ch[j]) {
i++;
j++;
}
else {
j = next[j];
}
}
if (j > T.length) {//匹配成功
printf("\n匹配成功!");
printf("\n模式串匹配成功的位置为%d.", i - T.length);
return OK;//返回的就是模式串的第一个元素的下标(也是位置),
//因为数组第一位不存元素,所以下标等于位置
}
else {
printf("\n匹配不成功!");
return ERROR;
}
}
//next[j]函数
void get_next(SString &T, int next[]) {
i = 1; next[1] = 0; j = 1;
while (i < T.length) {
if (j == 0 || T.ch[i] == T.ch[j]) {
++i; ++j;
next[i] = j;
}
else {
j = next[j];
}
}
}
int main() {
SString S;
SString T;
char ch1[25555];//定义一个数组,等下来放入主串
char ch2[255];//放入模式串
printf("==============BF算法================\n");
printf("请输入主串:");
scanf("%s", &ch1);
StringAssign(S, ch1);//引用此函数,可以把数组ch1的元素放进S.ch,作为主串
printf("\n请输入模式串:");
scanf("%s", &ch2);
StringAssign(T, ch2);
int pos = 1;//表示从第pos个元素开始查找
Index_BF(S, T, pos);//BF算法函数
printf("\n==============KMP算法================\n");
SString S1;
SString T1;
char ch3[255];//定义一个数组,等下来放入主串
char ch4[255];//放入模式串
printf("请输入主串:");
scanf("%s", &ch3);
StringAssign(S1, ch3);
printf("\n请输入模式串:");
scanf("%s", &ch4);
StringAssign(T1, ch4);
printf("模式串的next数组为:");
get_next(T1, next);
for (i = 0; i < T1.length; i++) {
printf("%d", next[i]);
}
Index_KMP(S1, T1, pos);
return 0;
}