KMP算法, 什么是KMP算法 ,暴力匹配 ,KMP算法实现

文章目录

    • KMP算法
      • 什么是KMP算法
      • 暴力匹配
      • KMP算法实现

KMP算法

什么是KMP算法

KMPKnuth、Morris和Pratt首字母的缩写,KMP也是由这三位学者发明(1977年联合发表论文)。

KMP主要应用在字符串的匹配,是一个解决模式串在文本串是否出现过,如果出现过,得出最早出现的位置的经典算法。其主要思想是:当出现字符串不匹配时,可以知道之前已经匹配的文本内容,可以利用这些信息避免从头再去匹配,从而提高匹配效率。

因此如何记录已经匹配的文本内容,才是KMP的重点~这也使得next数组派上了用场。

KMP算法就利用之前判断过信息,通过一个 next 数组,保存模式串中前后最长公共子序列的长度,每次回溯时,通过 next 数组找到前面匹配过的位置,省去了大量的计算时间。

在这里插入图片描述

暴力匹配

现给出一段字符串str1:“硅硅谷 尚硅谷你尚硅 尚硅谷你尚硅谷你尚硅你好”,和一段子字符串str2:“尚硅谷你”。

要求写出判断str1是否含有str2的代码,如果存在就返回第一次出现的位置,如果没有则返回-1。

说到字符串匹配,我们第一时间想到的是直接遍历字符串,看看是否存在。这种方法称为暴力匹配,抛开效率不说,这种方式是最直接,最简单的方式。

然而暴力匹配也是一种算法,一种解决方案,针对上述问题,我们可以得出暴力匹配算法的思路(假设现在 str1 匹配到 i 位置,子串 str2 匹配到 j 位置):

  • 如果当前字符匹配成功(即 str1[i] == str2[j]),则 i++,j++,继续匹配下一个字符
  • 如果失配(即 str1[i] != str2[j]),令 i = i - (j - 1),j = 0。相当于每次匹配失败时,i 回溯,j 被置为 0
  • 用暴力方法解决的话就会有大量的回溯,每次只移动一位,若是不匹配,移动到下一位接着判断,浪费了大量的时间(不可行!)

代码示例:

/**
 * 暴力匹配算法
 * @param str1
 * @param str2
 * @return 返回str2首次出现在str1的位置,匹配不到则返回-1
 */
public static int violenceMatch(String str1, String str2) {
    char[] s1 = str1.toCharArray();
    char[] s2 = str2.toCharArray();

    int i = 0; // 指向s1
    int j = 0; // 指向s2

    while (i < s1.length && j < s2.length) {
        if (s1[i] == s2[j]) {
            i++;
            j++;
        } else {
            // 只要有一个没有匹配上
            i = i - (j - 1);
            j = 0;
        }
    }
    // 判断是否匹配成功
    if (j == s2.length) {
        return i - j;
    }
    return -1;
}

main方法中测试暴力匹配:

public class AlgorithmUtils {
    public static void main(String[] args) {
        String str1 = "硅硅谷 尚硅谷你尚硅 尚硅谷你尚硅谷你尚硅你好";
        String str2 = "尚硅谷你";

        int index = AlgorithmUtils.violenceMatch(str1, str2);
        if (index != -1) {
            System.out.printf("第一次出现的位置是%d", index);
        }
    }
}

KMP算法实现

前面呢我们已经使用暴力匹配算法,完成了上述问题的求解!也知道了暴力匹配存在效率问题,那么KMP算法又是怎样实现呢?

为方便阐述,这里我们换个案例:现有两组字符串

str1 = “BBC ABCDAB ABCDABCDABDE”;
str2 = “ABCDABD”;

要求使用 KMP算法 完成判断,str1 是否含有 str2,如果存在,就返回第一次出现的位置,如果没有,则返回-1。

备注:不能使用简单的暴力匹配算法!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于单片机的太阳能数据采集系统(论文+源码)

1. 系统设计 在本次太阳能数据采集系统的设计中&#xff0c;以AT89C52单片机为主要核心&#xff0c;主要是由LCD液晶显示模块、存储模块、温度检测模块、串口通信模块&#xff0c;光照检测模块等组成&#xff0c;其实现了对太阳能板的温度&#xff0c;光照强度的检测和记录&…

在 App 设计工具的设计视图中布局 App

目录 自定义组件 对齐和间隔组件 组件分组 对组件重新排序 修改组件的 Tab 键焦点切换顺序 在容器中排列组件 在 App 设计工具中创建和编辑上下文菜单 创建上下文菜单 编辑上下文菜单 更改上下文菜单分配 App 设计工具中的设计视图提供了丰富的布局工具&#xff0c;用…

MySQL数据库 DDL

目录 一、DDL 二、操作数据库 三、操作表 四、数据类型 五、表操作案例 六、修改表 七、删除表 一、DDL Data Definition Language&#xff0c;数据定义语言&#xff0c;用来定义数据库对象(数据库&#xff0c;表&#xff0c;字段) 。 二、操作数据库 &#xff08;1&am…

java基础-1

byte&#xff1a;8位有符号二进制补码整数&#xff0c;占用1字节。 short&#xff1a;16位有符号二进制补码整数&#xff0c;占用2字节。 int&#xff1a;32位有符号二进制补码整数&#xff0c;占用4字节。 long&#xff1a;64位有符号二进制补码整数&#xff0c;占用8字节。…

理解Socket

前言 我在去年就学习过Java中Socket的使用&#xff0c;但对于Socket的理解一直都是迷迷糊糊的。看了网上很多关于Socket的介绍&#xff0c;看完还是不太理解到底什么是Socket&#xff0c;还是很迷。直到最近在学习计算机网络&#xff0c;我才对Socket有了一个更深地理解。之前一…

Netty—NIO万字详解

文章目录 NIO基本介绍同步、异步、阻塞、非阻塞IO的分类NIO 和 BIO 的比较NIO 三大核心原理示意图NIO的多路复用说明 核心一&#xff1a;缓存区 (Buffer)Buffer类及其子类Buffer缓冲区的分类MappedByteBuffer类说明&#xff1a; 核心二&#xff1a;通道 (Channel)Channel类及其…

在项目中,如何应对高并发流量

应对大流量的一些思路 首先&#xff0c;我们来说一下什么是大流量&#xff1f; 流量&#xff0c;我们很可能会冒出&#xff1a;TPS&#xff08;每秒事务量&#xff09;&#xff0c;QPS&#xff08;每秒请求量&#xff09;&#xff0c;1W&#xff0c;5W&#xff0c;10W&#x…

深度学习:自注意力机制(Self-Attention)

1 自注意力概述 1.1 定义 自注意力机制&#xff08;Self-Attention&#xff09;&#xff0c;有时也称为内部注意力机制&#xff0c;是一种在深度学习模型中应用的机制&#xff0c;尤其在处理序列数据时显得非常有效。它允许输入序列的每个元素都与序列中的其他元素进行比较&a…

HTTP深度解析:构建高效与安全网络的关键知识

1. HTTP基础及其组件 我首先想和大家分享的是HTTP的基础知识。HTTP&#xff0c;即超文本传输协议&#xff0c;是互联网上最常用的协议之一。它定义了浏览器和服务器之间数据交换的规则&#xff0c;使得网页内容可以从服务器传输到我们的浏览器上。想象一下&#xff0c;每当你点…

迅腾文化品牌网络推广助力企业:保持品牌稳定,发展更多消费者信任,提升品牌忠诚度

迅腾文化品牌网络推广助力企业&#xff1a;保持品牌稳定&#xff0c;发展更多消费者信任&#xff0c;提升品牌忠诚度 在当今快速发展的互联网时代&#xff0c;品牌网络推广已经成为企业发展的重要手段。迅腾文化作为专业的品牌网络推广公司&#xff0c;致力于帮助企业实现品牌…

产品Axure的元组件以及案例

前言 产品&#xff1c;Axure的安装以及组件介绍-CSDN博客经过上文我们可以知道我们Axure是一款适用于网站、移动应用和企业软件的交互式原型设计工具。它可以帮助用户创建高保真的交互式原型&#xff0c;包括线框图、流程图、模型、注释和规格等&#xff0c;以便与客户、开发人…

【Flink系列七】TableAPI和FlinkSQL初体验

Apache Flink 有两种关系型 API 来做流批统一处理&#xff1a;Table API 和 SQL Table API 是用于 Scala 和 Java 语言的查询API&#xff0c;它可以用一种非常直观的方式来组合使用选取、过滤、join 等关系型算子。 Flink SQL 是基于 Apache Calcite 来实现的标准 SQL。无论输…

K8S(二)—介绍

K8S的整体结构图 k8s对象 在 Kubernetes 系统中&#xff0c;Kubernetes 对象是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。 具体而言&#xff0c;它们描述了如下信息&#xff1a; 哪些容器化应用正在运行&#xff08;以及在哪些节点上运行&#xff09;可…

10进制和16进制数据互相翻译(windos版本)

window按winR键出现运行窗口&#xff0c;输入clac回车&#xff0c;进入计算器。 点击左上角&#xff0c;点击程序员&#xff0c;计算器就会变成可以进行进制转化的模式 鼠标点击DEC代表输入10进制&#xff0c;当我输入10时HEX变成A,A就是10转化16进制的数据&#xff0c; 反之如…

如何实现填表后分配序列号、活动抢票抽奖、自助分配座位号?

&#x1f4f1;发布者想要实现让用户在填表后自动分配序列号、座位号&#xff0c;或制作活动抢票抽奖系统&#xff0c;该如何实现&#xff1f; &#x1f4cc;使用教程 &#x1f4d6;案例1&#xff1a;制作活动抽奖系统 使用预置数据分配的随机分配功能&#xff0c;以活动抽奖为例…

实操Nginx(七层代理)+Tomcat多实例部署,实现负载均衡和动静分离

目录 Tomcat多实例部署&#xff08;192.168.17.27&#xff09; 1.安装jdk&#xff0c;设置jdk的环境变量 2.安装tomcat在一台已经部署了tomcat的机器上复制tomcat的配置文件取名tomcat1 ​编辑 编辑配置文件更改端口号&#xff0c;将端口号改为8081 启动 tomcat&#xff…

前端自定义验证码,校验验证码,验证码时效

最近做的项目&#xff0c;不需要后端接口&#xff0c;只需要前端验证&#xff0c;如图 初始页面 获取验证码 验证码的文件&#xff0c;直接复制就行 <template><div class"s-canvas"><canvasid"s-canvas":width"contentWidth":…

【Axure RP9】的详细安装及Axure入门应用

目录 一 Axure入门安装 1.1 Axure是什么? 1.2 Axure应用场景 1.3 Axure安装 1.3.1 汉化 1.3.2 授权 二, Axure应用 1.1 Axure软件界面概述 1.2 Axure的应用 1.2.1备份 1.2.2 视图显示及网格设置 1.2.3 生成HTML文件 1.2.4 备注说明 一 Axure入门安装 1.1 Axure…

吉林省文旅厅联合高德地图上线自驾游精品线路指南

12月15日消息&#xff0c;今日&#xff0c;吉林省文化和旅游厅联合高德地图推出“吉林省自驾游精品线路指南”&#xff0c;依托全省冬夏两季特色资源&#xff0c;推出了基于位置的8条自驾游品牌路线、百余个吉林省重点旅游场景&#xff0c;游客可以根据季节、地理位置、资源类型…

SoC中跨时钟域的信号同步设计(单比特同步设计)

一、 亚稳态 在数字电路中&#xff0c;触发器是一种很常用的器件。对于任意一个触发器&#xff0c;都由其参数库文件规定了能正常使用的“建立时间”&#xff08;Setup time&#xff09;和“保持时间”&#xff08;Hold time &#xff09;两个参数。“建立时间”是指在时钟…