KMP算法

本文深入讲解了KMP算法的工作原理及实现过程,并提供了完整的C++代码示例。通过本文,读者可以了解如何构造next数组以及如何利用该数组提高模式匹配效率。

这个算法很经典,我花了一个下午加一个晚上才搞明白!我佩服想出这个算法的人精湛而严密的数学思维!向他们致敬!这个算法,应该是我到目前为止见过的最美丽的算法了。

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
void get_next(char T[],int next[],int len_T)//获取next数组的方法,T[]子串
{
    int i,j;//同样定义两个指针
    i=2;//i在后面,i现在虽然为2,实则考察的是i+1,即3,请读者自行领会
    j=1;//j在前面
    next[1]=0;//这是必然的
    next[2]=1;//这是必然的
    while(i<len_T)//注意,这里是<而不是<=,因为每到i,其实是考察的i+1的next的值!
    {
        if(T[i]==T[j])//如果相等,就++,然后next[i]就是j
        {
            i++;
            j++;
            next[i]=j;//这个赋值语句暗藏很多数学道理,读者请自行领悟,具体证明见严蔚敏83页公式推导论证
        }
        else
        {
            if(j==1)//说明j已经回溯到尽头了,此时j为1,因此i必须前进一格,对应于严蔚敏81页公式4-5中的其他情况,此时找不到这个k,因此置next[i]为1
            {
                i++;
                next[i]=1;
            }
            else//这个说明还没有回溯到尽头,所以就继续回溯呗!
                j=next[j];
        }
    }
}
int KMP(char S[],char T[],int pos,int next[],int len_S,int len_T)//KMP算法主体部分,S为主串,T为子串,pos是规定从主串下标为pos的地方开始模式匹配
{
    int i,j;//i,j分别为主串和子串的指针
    i=pos,j=1;
    while(i<=len_S&&j<=len_T)//遍历主串和子串
    {
        if(S[i]==T[j])//如果相等,i和j都++
        {
            i++;
            j++;
        }
        else//如果不等,就要看j的值了
        {
            if(j==1)//如果此时回溯到尽头,i就必须++
                i++;
            else
                j=next[j];//否则就回溯呗
        }
    }
    if(j>len_T)//这个要理解,如果我大于T[0],说明我此时已经全部匹配成功啦,i就回退T的长度,就是匹配成功字符串的第一个数组下标
        return i-len_T;
    return -1;//匹配不成功就返回-1
}
int main()
{
    char c,S[100],T[100];
    int next[100],ret,i,len_S,len_T;
    i=1;
    cout<<"请输入主串,以回车结束!"<<endl;
    /*下标从1开始进行输入S*/
    c=getchar();
    while(c!='\n')
    {
        S[i++]=c;
        c=getchar();
    }
    S[i]='\0';//C语言基础知识
    len_S=i-1;//考察字符串基本功
    /*下标从1开始进行输入T*/
    i=1;
    cout<<"请输入子串,以回车结束!"<<endl;
    c=getchar();
    while(c!='\n')
    {
        T[i++]=c;
        c=getchar();
    }
    T[i]='\0';
    len_T=i-1;
    get_next(T,next,len_T);
    ret=KMP(S,T,1,next,len_S,len_T);
    if(ret!=-1)
        cout<<"首次出现子串的下标为"<<ret<<"!"<<endl;
    else
        cout<<"找不到!"<<endl;
    return 0;
}

内容概要:本文系统介绍了算术优化算法(AOA)的基本原理、核心思想及Python实现方法,并通过图像分割的实际案例展示了其应用价值。AOA是一种基于种群的元启发式算法,其核心思想来源于四则运算,利用乘除运算进行全局勘探,加减运算进行局部开发,通过数学优化器加速函数(MOA)和数学优化概率(MOP)动态控制搜索过程,在全局探索与局部开发之间实现平衡。文章详细解析了算法的初始化、勘探与开发阶段的更新策略,并提供了完整的Python代码实现,结合Rastrigin函数进行测试验证。进一步地,以Flask框架搭建前后端分离系统,将AOA应用于图像分割任务,展示了其在实际工程中的可行性与高效性。最后,通过收敛速度、寻优精度等指标评估算法性能,并提出自适应参数调整、模型优化和并行计算等改进策略。; 适合人群:具备一定Python编程基础和优化算法基础知识的高校学生、科研人员及工程技术人员,尤其适合从事人工智能、图像处理、智能优化等领域的从业者;; 使用场景及目标:①理解元启发式算法的设计思想与实现机制;②掌握AOA在函数优化、图像分割等实际问题中的建模与求解方法;③学习如何将优化算法集成到Web系统中实现工程化应用;④为算法性能评估与改进提供实践参考; 阅读建议:建议读者结合代码逐行调试,深入理解算法流程中MOA与MOP的作用机制,尝试在不同测试函数上运行算法以观察性能差异,并可进一步扩展图像分割模块,引入更复杂的预处理或后处理技术以提升分割效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值