bf算法,需要对主串进行回溯;kmp算法,去掉了回溯过程,更为快速.(以下代码的next算法还需优化)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define MAXSIZE 20
/*
串的模式匹配算法:BF朴素模式匹配、KMP(三个提出者的名字首字母)模式匹配算法
*/
//BF模式匹配算法
int indexBF(char s[],char t[]){
for (int i=0;i<=strlen(s)-strlen(t);i++){
for(int j=0,k=i;j<strlen(t);j++,k++){
if (s[k]!=t[j]){
break;
}else{
if (j==strlen(t)-1&&s[k]==t[j]){
return i;
}
}
}
}
return -1;
}
//求next数组:结果是正确的,但是设计应该有问题,效率低,待优化
int* getNext(char t[]){
int len = strlen(t);
int *next=(int *)malloc(sizeof(int)*(len+1));
//计算最长前后缀匹配长度
next[1] = 0;
next[2] = 1;
for (int i=2;i<len;i++){
//找到中间的位置开始匹配第一个,也就是最长的那个
int k=0;//k为前缀位置起始位置,j为后缀起始位置
for(int j=1;j<i;j++){
if (t[k]==t[j]){
k++;
}else{
if (k>0){
j-=k;
}
k=0;
}
}
next[i+1]=k+1;
}
return next;
}
//kmp算法:字串(模式串)中重复的较多时有优势,O(m+n),不回溯
int indexKMP(char s[],char t[]){
int *next=getNext(t);
int j=0;
int i=0;
for (;i<strlen(s)&&j<strlen(t);i++){//不回溯
if (s[i]==t[j]){
j++;
}else{
j=next[j+1];//next数组从1开始
}
}
if (j>=strlen(t)){
return i-strlen(t);
}
return -1;
}
int main(){
char s[]="BBCABCDABABCDABCDABDE";
char t[]="ABCDABD";
clock_t start = clock();
printf("kmp第一次匹配的下标:%d\n",indexKMP(s,t));
clock_t t1 = clock();
double duration = (double)(t1 - start) / CLOCKS_PER_SEC * 1000;
printf("1time:%.3f\n",duration);
printf("bf第一次匹配的下标:%d\n",indexBF(s,t));
clock_t t2 = clock();
duration = (double)(t2 - t1) / CLOCKS_PER_SEC * 1000;
printf("2time:%.3f\n",duration);
return 0;
}