C++实现KMP(Knuth-Morris-Pratt)字符串匹配算法

#include"iostream"


using namespace std;

// 暴力匹配算法
bool string_match(char *mains,unsigned int mainslength,char *childs,int childslength)
{
    int j;
    for(int i=0;i<mainslength;i++)
    {
        for(j=0;j<childslength;j++)
        {
            // 如果不相等
            if(mains[i+j]!=childs[j])
            {
                break;
            }
        }
        if(j==(childslength-1))
        {
            // 成功匹配
            return true;
        }
        
    }
    // 匹配失败
    return false;

}


// 字符串匹配算法:kmp
// 生成前缀表
unsigned int *gen_prefix(char *p,unsigned int length)
{
    // 得到p的长度
    unsigned int m =length;
    // 创建一个大小为m的数组
    unsigned int *w =new unsigned int[m];
    // 第一个默认为0
    w[0]=0;
    // 
    unsigned int k=0;

    // 从第2个到最后一个
    for(int q=1;q<m;q++)
    {
        //如果满足这个条件
        while(k>0 && p[k]!=p[q])
        {
            // 就把前一个的给k
            k=w[k-1];
        }
        // 如果这个字符相等
        if(p[k]==p[q])
        {
            // k++
            k++;
        }
        // 得到新的前缀数
        w[q]=k;
    } 
    // 返回前缀数组
    return w;
}
// kmp字符串匹配算法
bool kmp_match(char *T,unsigned int length_T,char *P,unsigned int length_P)
{
    // 两个数组的边界
    unsigned int n=length_T;
    unsigned int m=length_P;
    // 得到前缀数组
    unsigned int *w = gen_prefix(P,length_P);

    unsigned int q =0;
// 匹配到最后一个字符
    for(int i=0;i<n;i++)
    {
        // 如果满足一下条件
        while(q>0 && P[q]!=T[i])
        {
            // q就是前一个字符
            q=w[q-1];
        }
        // 如果两个字符相等
        if(P[q]==T[i])
        {
            q++;
        }
        // 如果q和m相等,匹配成功
        if(q==m)
        {
            return true;
        }
    }
    // 匹配失败
    return false;
}

int main(int argc,char *argv[])
{
    // 字符串主串
    char mains[]="abaacababcac";
    // 字符串子串
    char childs[]="cabab";

    cout<<kmp_match(mains,sizeof(mains)-1,childs,sizeof(childs)-1);




    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值