当前位置: 首页 > news >正文

李春葆、严蔚敏关于KMP算法的next数组值差1

【算法解析】
曾经在 https://blog.csdn.net/hnjzsyjyj/article/details/127086502 提到,在KMP算法的众多实现中,有多种定义next数组的方式。所以在使用和查看别人代码时,要特别注意KMP算法的next数组的定义,以免发生混淆。如:
• 严蔚敏《数据结构》将模式串下标从1开始计数,故定义next[1]=0,next[2]=1;
• 李春葆《数据结构》将模式串下标从0开始计数,故定义next[0]=-1,next[1]=0。

由于字符串的下标在C++中从0开始,因此在利用C++进行KMP算法的设计中,将next数组下标从0开始考虑,是很自然的事情。据此,建议选择李春葆《数据结构》中关于模式串下标的定义,即从0开始考虑,据此可定义next[0]=-1,next[1]=0。之后,按照“
(1)若第i-1位的字符与第j位的字符相等,则next[i]=j+1; (2)若直到第0位依然没有字符与第i-1位的字符相等,则next[i]=0”构建next数组。

通过观察,发现“
李春葆、严蔚敏关于KMP算法的next数组值差1”。这就给出了启发。即:
如果李春葆定义法的next数组值(以“-1 0 ”开头),利用 cout<<next[i]; 输出。
那么严蔚敏定义法的next数组值(以“0 1”开头),便可利用 
cout<<next[i]+1; 输出。
也就是说,
仅需修改一条语句,便可复用代码,实现李春葆定义法、严蔚敏定义法中next数组值的输出。

【输出李春葆定义法next数组值的算法代码】

#include<iostream>
using namespace std;

const int maxn=100;
int ne[maxn];

void getNext(string s) {
    int len=s.length(); 
    int i=0, j=-1;
    ne[0]=-1;
    while(i<len) {
        if(j==-1 || s[i]==s[j]) {
            ne[++i]=++j;
        } else j=ne[j];
    }
}

int main() {
    string T;
    getline(cin,T);
    getNext(T);
    for(int i=0; i<T.length(); i++) {
        cout<<ne[i]<<" ";
    }

    return 0;
}


/*
input: ababaaababaa

output: -1 0 0 1 2 3 1 1 2 3 4 5
*/


【输出严蔚敏定义法next数组值的算法代码】

#include<iostream>
using namespace std;

const int maxn=100;
int ne[maxn];

void getNext(string s) {
    int len=s.length();
    int i=0, j=-1;
    ne[0]=-1;
    while(i<len) {
        if(j==-1 || s[i]==s[j]) {
            ne[++i]=++j;
        } else j=ne[j];
    }
}

int main() {
    string T;
    getline(cin,T);
    getNext(T);
    for(int i=0; i<T.length(); i++) {
        cout<<ne[i]+1<<" ";
    }

    return 0;
}


/*
input: ababaaababaa

output: 0 1 1 2 3 4 2 2 3 4 5 6
*/


【参考文献】
https://blog.csdn.net/hnjzsyjyj/article/details/127086502
https://blog.csdn.net/hnjzsyjyj/article/details/127105603
https://blog.csdn.net/hnjzsyjyj/article/details/127112363

相关文章:

  • 驱动开发:通过ReadFile与内核层通信
  • Superset embed Dashboard到React App
  • Kotlin协程基础-CoroutineContext
  • Node学习二十 —— 构建和使用HTTP中间件
  • 解决驱动开发中并发和竞争中的问题----------自旋锁
  • 【VIO】第1讲 IMU 传感器
  • 每日三题 9.30
  • C++ Reference: Standard C++ Library reference: C Library: cmath: llrint
  • NNDL实验: Moon1000数据集 - 弯月消失之谜
  • ROC-RK3588-PC 八核8K人工智能开源主板
  • 2022新版PMP考试有哪些变化?
  • hive集群加了个参数后,union all的任务都执行不了影响业务
  • 攻防演练中防守方的防护措施.
  • 鲁棒的非负监督低秩鉴别嵌入算法
  • 第一季:12Linux常用服务类相关命令【Java面试题】
  • 【跃迁之路】【699天】程序员高效学习方法论探索系列(实验阶段456-2019.1.19)...
  • Git学习与使用心得(1)—— 初始化
  • Javascripit类型转换比较那点事儿,双等号(==)
  • maya建模与骨骼动画快速实现人工鱼
  • Mithril.js 入门介绍
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • Vue实战(四)登录/注册页的实现
  • Vue--数据传输
  • 关于Flux,Vuex,Redux的思考
  • 如何进阶一名有竞争力的程序员?
  • 扫描识别控件Dynamic Web TWAIN v12.2发布,改进SSL证书
  • 3月7日云栖精选夜读 | RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占绝对优势 ...
  • ​批处理文件中的errorlevel用法
  • #if 1...#endif
  • #include<初见C语言之指针(5)>
  • #我与Java虚拟机的故事#连载07:我放弃了对JVM的进一步学习
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (动态规划)5. 最长回文子串 java解决
  • (个人笔记质量不佳)SQL 左连接、右连接、内连接的区别
  • (三)终结任务
  • (算法二)滑动窗口
  • (转)树状数组
  • .\OBJ\test1.axf: Error: L6230W: Ignoring --entry command. Cannot find argumen 'Reset_Handler'
  • .net core 3.0 linux,.NET Core 3.0 的新增功能
  • .Net Remoting(分离服务程序实现) - Part.3
  • .NET3.5下用Lambda简化跨线程访问窗体控件,避免繁复的delegate,Invoke(转)
  • .net6+aspose.words导出word并转pdf
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证
  • .Net高阶异常处理第二篇~~ dump进阶之MiniDumpWriter
  • @html.ActionLink的几种参数格式
  • @Transaction注解失效的几种场景(附有示例代码)
  • [ IOS ] iOS-控制器View的创建和生命周期
  • [2016.7 day.5] T2
  • [20171106]配置客户端连接注意.txt
  • [8-23]知识梳理:文件系统、Bash基础特性、目录管理、文件管理、文本查看编辑处理...
  • [Android] 修改设备访问权限
  • [Android]使用Git将项目提交到GitHub