KMP算法

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

内容概要:本文详细介绍了名为MoSca的系统,该系统旨在从单目随意拍摄的视频中重建和合成动态场景的新视角。MoSca通过4D Motion Scaffolds(运动支架)将视频数据转化为紧凑平滑编码的Motion Scaffold表示,并将场景几何和外观与变形场解耦,通过高斯融合进行优化。系统还解决了相机焦距和姿态的问题,无需额外的姿态估计工具。文章不仅提供了系统的理论背景,还给出了基于PyTorch的简化实现代码,涵盖MotionScaffold、GaussianFusion、MoScaSystem等核心组件。此外,文中深入探讨了ARAP变形模型、2D先验到3D的提升、动态高斯表示、相机参数估计等关键技术,并提出了完整的训练流程和性能优化技巧。 适用人群:具备一定计算机视觉和深度学习基础的研究人员和工程师,特别是对动态场景重建和新视角合成感兴趣的从业者。 使用场景及目标:①从单目视频中重建动态场景的新视角;②研究和实现基于4D Motion Scaffolds的动态场景表示方法;③探索如何利用预训练视觉模型的先验知识提升3D重建质量;④开发高效的动态场景渲染和优化算法。 其他说明:本文提供了详细的代码实现,包括简化版和深入扩展的技术细节。阅读者可以通过代码实践加深对MoSca系统的理解,并根据具体应用场景调整和扩展各个模块。此外,文中还强调了物理启发的正则化项和多模态先验融合的重要性,帮助实现更合理的变形和更高质量的渲染效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值