串的模式匹配算法

文章提供了C语言实现的BF(朴素)模式匹配算法和KMP模式匹配算法。BF算法存在回溯,效率较低;KMP算法利用next数组优化,避免了回溯,提高了效率。代码中还包含了next数组的计算函数。通过示例比较了两种算法在匹配字符串时的时间消耗。
摘要由CSDN通过智能技术生成

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值