C语言数据结构+KMP算法next数组优化计算方法+优化后子串匹配代码实现

news2024/11/26 8:26:01

KMP算法next数组优化版

    • 一.计算根据下列模式串计算出next数组
    • 二.优化next数组
    • 三.用优化后next的数组代码实现子串的匹配
    • 总结

通过我之前那篇KMP算法的讲解,我们可以快速手算KMP算法的next数组,但是之前计算的next数组在一些情况下会有缺陷,比如模式串’aaaab’和主串’aaabaaaab’进行匹配

一.计算根据下列模式串计算出next数组

令模式串指针为j
在这里插入图片描述

当第一个元素不匹配时,下一次匹配还是要从模式串的第一个元素与主串匹配,其实我们可以直接写next [1] = 0;,就是当模式串第一个元素就不匹配时next数组对应值直接写0,这样写在我们实现代码时就可以让j = 0时主串和模式串的指针同时往后移动
在这里插入图片描述

当第二个元素不匹配时,在匹配失败的元素前面画一条线,然后模式串右移,直到左边没有元素或者左边元素都匹配成功的时候就停下来,从下图可以看到模式串是从第一个元素开始匹配,所以next[1] = 1,这个也可以直接写1,因为在每一个模式串第一个元素不匹配时,next[2]=1

在这里插入图片描述
当第三个元素不匹配时,在匹配失败的元素前面画一条线,然后模式串右移,直到左边没有元素或者左边元素都匹配成功的时候就停下来,从下图可以看出next[3]=2
在这里插入图片描述
右移,下一次模式匹配的是第二个元素,所以next等于2
在这里插入图片描述
当第四个元素不匹配时,在匹配失败的元素前面画一条线,然后模式串右移,直到左边没有元素或者左边元素都匹配成功的时候就停下来,从下图可以看出next[4]=3
在这里插入图片描述
当第五个元素不匹配时,在匹配失败的元素前面画一条线,然后模式串右移,直到左边没有元素或者左边元素都匹配成功的时候就停下来,从下图可以看出next[5]=4
在这里插入图片描述
综上所述,next数组的为[0,1,2,3,4]

二.优化next数组

通过以上我们会发现,当模式串第二个元素不匹配时,我们默认是将模式串右移一位,让模式串第一个元素与之进行比较,然而这里我们可以看到模式串的第一个和第二个元素是同一个,那么就说第一个元素一定与之不匹配,此时我们就可以直接把next[2]设置为0;
原来匹配失败比较位置
在这里插入图片描述
优化后
在这里插入图片描述

其他的也是同样的方式

通过以上我们会发现,当模式串第3个元素不匹配时,我们默认是将模式串右移一位,让模式串第2个元素与之进行比较,然而这里我们可以看到模式串的第2个和第3个元素是同一个,那么就说第2个元素一定与之不匹配,此时我们就可以直接把next[2]设置为0;
在这里插入图片描述
第四个元素不匹配也是和上面一样让next[4] =0

但是当第五个元素不匹配时,我们只能直到第五个元素一定不是b,但是可能是a,所以我们这里就要模式串的第四个元素与之比较,所以next[5]=4
在这里插入图片描述
综上所述,可以得到优化后的next数组等于[0,0,0,0,4]

三.用优化后next的数组代码实现子串的匹配

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
void get_next(char* s, int* next) {
    int len = strlen(s);
    next[0] = -1;
    int k = -1, j = 0;
    while (j < len - 1) {
        if (k == -1 || s[j] == s[k]) {
            ++j;
            ++k;
            if (s[j] != s[k]) {
                next[j] = k;
            }
            else {
                next[j] = next[k];
            }
        }
        else {
            k = next[k];
        }
    }
}
int kmp(char* s, char* p, int* next) {
    int slen = strlen(s);
    int plen = strlen(p);
    int i = 0, j = 0;
    while (i < slen && j < plen) {
        if (j == -1 || s[i] == p[j]) {
            ++i;
            ++j;
        }
        else {
            j = next[j];
        }
    }
    if (j == plen) {
        return i - j;
    }
    else {
        return -1;
    }
}
int main() {
    char s[] = "aaabaaaab";
    char p[] = "aaaab";
    int next[5];
    get_next(p, next);
    int pos = kmp(s, p, next);
    if (pos != -1) {
        printf("子串在主串的%d元素后\n", pos);
    }
    else {
        printf("匹配失败\n");
    }
    return 0;
}

代码运行:
在这里插入图片描述

总结

通过以上的流程图讲解我们可以清楚的了解到优化KMP算法实际就是通过尽可能的减少子串与子串之间的比较次数从而达到高效的子串匹配,最主要我们要先学会next数组的计算再去了解优化后的next数组,这样才会事半功倍,希望本篇文章可以给大家带来帮助!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/459699.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人人都能用,3s学会加密你的网址变成ooo

文章目录 1 前言2 原理及使用方法3 这玩意有什么用3.1 简单加密网址3.2 隐藏二级目录3.3 彩蛋&#xff1a;无限月读3.4 探讨性的加密应用 4 转换的代码4.1 将字符转为utf8数组4.2 将utf8数组转换为字符串4.3 最终转换4.4 用R来实现 5 讨论 1 前言 大家可以复制一下这个网址到浏…

[JavaEE初阶] 类加载机制

在真正的战争到来之前,尽可能地变得强大吧~ 文章目录 前言1. 类加载1.1 类加载的过程1.2 类加载的时机1.3 双亲委派模型 前言 这个问题是面试经典题,让我们来求甚解吧~ 1. 类加载 1.1 类加载的过程 如下图 加载,找到.class文件,读取文件内容验证,验证.class文件的格式是否…

IntelliJ IDEA 接入ChatGPT (免费,无需注册)生产力被干爆了!

IntelliJ IDEA 接入ChatGPT 前言 : 今天给大家介绍一款好用的 IntelliJ IDEA ChatGPT 插件 可以帮助我们写代码&#xff0c;以及语言上的处理工作&#xff0c;以及解释代码。让我们的生产力大大提高&#xff01; 一. ChatGPT-Plus 功能介绍 支持最新idea版本AI询问功能,写好…

记录一次adb+frida+hook学习经过

adb连接模拟器 adb devices 查看adb 连接设备 offline 表示设备未连接成功或无响应&#xff0c;device 设备已连接 未连接就使用adb connect 127.0.0.1:端口号 各种模拟器端口号及模拟器连接方式_雷电模拟器 调式串口_宋学慧的博客-CSDN博客 举个栗子 常见adb命令 adb vers…

NXP公司LPC21XX+PID实现稳定温度控制

本例使用的是LPC21XX系列芯片提供的PWM功能实现稳定的温度控制。首先我们获得当前环境温度之后&#xff0c;再用设定的温度与当前温度相减&#xff0c;通过PID算法计算出当前输出脉宽&#xff0c;并将其输出到L298N模块中&#xff0c;使加热丝发热&#xff0c;形成闭环&#xf…

Java核心技术 卷1-总结-18

Java核心技术 卷1-总结-18 同步Volatile域final变量原子性死锁线程局部变量锁测试与超时读/写锁 同步 Volatile域 多处理器的计算机能够暂时在寄存器或本地内存缓冲区中保存内存中的值。结果是&#xff0c;运行在不同处理器上的线程可能在同一个内存位置取到不同的值。编译器…

建仓价和持仓价的应用:如何开仓如何持仓

建仓、持仓&#xff0c;是交易中绕不开的话题&#xff0c;没有建仓、持仓&#xff0c;何来建仓价、持仓价呢&#xff1f;所以这也是基础问题。不过作为市场形式的表现来说&#xff0c;建仓、持仓到后来的平仓贯彻始终&#xff0c;虽然是基础问题&#xff0c;也是后面登堂入室、…

【图数据库实践教程】Ubuntu22.04-Neo4j中文版安装及导入owl文件(通用教程)

文章目录 0. 环境准备0.1 静态配置IP&#xff1a;192.168.1.54&#xff0c;及网卡类型&#xff1a;NAT模式0.2 激活root用户&#xff1a;0.3 更改apt国内镜像源&#xff08;下载快&#xff09;0.4 关闭相关防火墙等保证网络顺畅 1. 相关软件安装1.1 安装好服务器内的相关软件1.…

FL Studio2023中文版数字音频工作站(DAW)软件

FL Studio21水果软件能支持制作各种音乐类型&#xff0c;除了最擅长的电子音乐&#xff0c;还可以任意创作流行音乐、古典音乐、民族音乐、乡村音乐、爵士乐等等&#xff0c;没有音乐类型的限制&#xff0c;让你的音乐突破想象力的限制。 FL Studio 2023中文版是数字音频工作站…

LINUX的系统管理与维护命令

文章目录 一、LINUX的系统管理与维护命令总结 一、LINUX的系统管理与维护命令 - Linux ls命令:显示指定工作目录下的内容 Linux pwd命令:显示当前工作目录 Linux cd命令:切换工作目录 Linux date命令:显示或设置系统时间 Linux su命令:切换用户 Linux clear命令:清除屏幕 Li…

5种简单快速的方法解除PDF文件密码保护

PDF 文件已经成为了我们日常工作、学习中广泛使用的文档格式之一。为了对重要的 PDF 文件进行保护&#xff0c;我们有时需要添加密码保护功能来防止未授权访问或修改。但是&#xff0c;如果您的 PDF 文件已经有了密码保护&#xff0c;而您需要快速访问和编辑它们&#xff0c;那…

机器人工程师与孔乙己文学

本文内容严格按创作模板发布&#xff1a; 孔乙已是鲁迅笔下人物&#xff0c;穷困流倒还穿着象征读书人的长衫&#xff0c;迁腐、麻木。最近&#xff0c;大家自我调佩是“当代孔乙己”&#xff0c;学历成为思想负担&#xff0c;找工作时高不成低不就。你可以从以下几个角度说说…

static_cast、dynamic_cast和reinterpret_cast区别和联系

其实网上相关的资料不少&#xff0c;但是能够说清楚明白这个问题的也不多。 于是&#xff0c;我尝试着问了一下AI&#xff0c;感觉回答还可以&#xff0c;但是需要更多的资料验证。 让我们先看看AI是怎么回答这个问题的。 static_cast、dynamic_cast和reinterpret_cast都是C中…

“SCSA-T学习导图+”系列:路由技术之OSPF入门

本期引言&#xff1a; 路由技术是网络环境中&#xff0c;为不同的节点传输数据提供传输路径的技术&#xff0c;企业网络的拓扑一般会比较复杂&#xff0c;不同的部门或者总部和分支可能处于不同的网段中&#xff0c;此时就需要使用路由协议来连接不同的网段&#xff0c;实现数…

Parker机电产品(运动控制/伺服电机/直线电机)在FPD行业应用

Parker新控制器-PAC PAC集高级逻辑控制&#xff0c;多轴运动&#xff0c;信号处理和webpublished可视化功能。 采用工业主流的EtherCAT运动控制协议&#xff0c;I/O扩展和第三方设备链接&#xff0c;结合应用开发软件PARKERAutomation Manager &#xff0c; PAC能为OEM需要的…

微信仿真平台的设计和实现(设计+源码)_kaic

摘要 现如今&#xff0c;科技的发展带动着环保方式的更新&#xff0c;Internet是一个不断的开展和不停的扩充数据潮流&#xff0c;有了它&#xff0c;我们可以快速、容易地在世界的任何角落进行沟通&#xff0c;获取更多的信息与资料。Internet可以提供大量信息资源和文案数据库…

临近五一,游玩地点想好了吗,Python帮你查找旅游景点的详细数据

前言 好不容易没有了疫情&#xff0c;三年整整三年&#xff0c;都要把我憋死了&#xff0c;想到去年暑假的时候&#xff0c;准备去厦门&#xff0c;攻略做好了&#xff0c;厦门疫情来了&#xff0c;想着转去济南也是这样&#xff0c;去三亚&#xff0c;结果收到好几万人都被留…

5G网络切片路由选择策略介绍

终端保存的NSSP(Network Slice Selection Policy)策略来源于网络侧。 NSSP规则是将应用程序匹配到S-NSSAI(Single network slice selection assistance information),并将应用程序绑定到现有PDU会话或发起新的PDU会话。 NSSP功能 NSSP的作用就是为应用程序选择S-NSSAI和…

HashMap如何解决哈希冲突

HashMap如何解决哈希冲突 Hash算法和Hash表Hash冲突解决哈希冲突的方法开放地址法链式寻址法再hash法建立公共溢出区 Hash算法和Hash表 Hash算法就是把任意长度的输入通过散列算法编程固定长度的输出。这个输出结果就是一个散列值。 Hash表又称为“散列表”&#xff0c;它是通…

LVS负载均衡群集部署——DR直接路由

目录 一、LVS-DR模式二、LVS-DR模式的特点三、LVS-DR中的ARP问题 二、LVS负载均衡群集-DR模式部署1.配置nfs共享&#xff08;192.168.154.10&#xff09;2.部署第一台nginx服务&#xff08;192.168.154.11&#xff09;3.部署第二台nginx服务&#xff08;192.168.154.12&#xf…