字符串匹配算法知多少?

在这里插入图片描述

文章目录

    • BF算法
    • RK算法
    • 编辑器中的全局替换方法:BM算法
      • 坏字符
      • 好后缀规则
      • 代码实现
    • KMP算法

一说到字符串匹配算法,不知道会有多少小伙伴不由自主的想起那个kmp算法呢?

想到是很正常的,谁让它那么优秀呢。


BF算法

不要被事物的表面现象所迷惑,这个算法全称:Brute Force,有个拉风的中文名:暴力匹配算法。

能想明白了吧。

如果模式串长度为 m,主串长度为 n,那在主串中,就会有 n-m+1 个长度为 m 的子串,我们只需要暴力地对比这 n-m+1 个子串与模式串,就可以找出主串与模式串匹配的子串。

1、从头开始往后遍历匹配;
2、遇上不对了,就回头,把子串和主串的匹配头后移一位
3、重复以上。直到找到或确定找不到。

复杂度很高啊,但是在实际开发中也是比较常用的。为什么呢?
真当天天都有成千上万个字符的主串让我们去匹配吗?一般都比较短,而且,统计意义上,算法执行效率不会真的到M*N的地步。

理论还是要结合实际的。

还有另一个原因,就是它好写。当然kmp现在更好写,因为封装好了。
我说的是类似的场景,没有封装好的函数时候,好写,好改。


RK算法

RK 算法的思路是这样的:我们通过哈希算法对主串中的 n-m+1 个子串分别求哈希值,然后逐个与模式串的哈希值比较大小。如果某个子串的哈希值与模式串相等,那就说明对应的子串和模式串匹配了(这里先不考虑哈希冲突的问题,后面我们会讲到)。因为哈希值是一个数字,数字之间比较是否相等是非常快速的,所以模式串和子串比较的效率就提高了。

有没有方法可以提高哈希算法计算子串哈希值的效率呢?

我们假设要匹配的字符串的字符集中只包含 K 个字符,我们可以用一个 K 进制数来表示一个子串,这个 K 进制数转化成十进制数,作为子串的哈希值。

比如要处理的字符串只包含 a~z 这 26 个小写字母,那我们就用二十六进制来表示一个字符串。我们把 a~z 这 26 个字符映射到 0~25 这 26 个数字,a 就表示 0,b 就表示 1,以此类推,z 表示 25。

在这里插入图片描述

这里有一个小细节需要注意,那就是 26^(m-1) 这部分的计算,我们可以通过查表的方法来提高效率。我们事先计算好 26^0、26^1、26^2……26^(m-1),并且存储在一个长度为 m 的数组中

模式串哈希值与每个子串哈希值之间的比较的时间复杂度是 O(1),总共需要比较 n-m+1 个子串的哈希值,所以,这部分的时间复杂度也是 O(n)。所以,RK 算法整体的时间复杂度就是 O(n)。

但是呢,还有一个很致命的问题,叫做数值过大。
以幂增的速度是非常快的,用不了多久int就hold不住了啊,那要怎么办?难道我们前面所做的努力都白费了?

其实不然。
比方说我们可以改乘为加,当我们匹配到一样的哈希值的时候,再打开子串进行比对,因为相加的话是会有哈西冲突的。

此外,我们还可以加点优化,一边对主串构建,一边对子串进行匹配,如果一样的话就不继续计算后面的hash了。
该省的时候就要省,该花的时候就要花。


编辑器中的全局替换方法:BM算法

用过吗?比方说要在我这篇博客里找出全部的“主串”这个词,有没有想过其底层的原理?

这是一个性能优于KMP的算法。

坏字符

BM 算法的匹配顺序比较特别,它是按照模式串下标从大到小的顺序,倒着匹配的。

我们从模式串的末尾往前倒着匹配,当我们发现某个字符没法匹配的时候。我们把这个没有匹配的字符叫作坏字符(主串中的字符)

在这里插入图片描述

这时候该如何操作呢?我们去子串中寻找这个坏字符,如果找到了,就让两个字符的位置对上,继续往后,如果没有找到,就将整个子串移动到坏字符后面。

很显然,这会儿没找到。

在这里插入图片描述

接下来该怎么滑呢?又是个坏字符。
但是在子串中找到了那个坏字符,那就将两个字符的位置对上。

在这里插入图片描述

模式串中有对应的坏字符时,让模式串中 最靠右 的对应字符与坏字符相对。

在这里插入图片描述

但是呢,用这个规则还是不太够用的,有些个特殊情况吧,它会导致不但不会向后滑动模式串,还有可能会倒推、

比如说主串:kkkkkkkkkkkkkkkkkk,模式串是 akk


好后缀规则

在这里插入图片描述

如果模式串中存在已经匹配成功的好后缀,则把目标串与好后缀对齐,然后从模式串的最尾元素开始往前匹配。

在这里插入图片描述

如果无法找到匹配好的后缀,找一个匹配的最长的前缀,让目标串与最长的前缀对齐:
在这里插入图片描述

在这里插入图片描述

如果完全不存在和好后缀匹配的子串,则右移整个模式串


代码实现

难顶,我一定会回来的

// a,b 表示主串和模式串;n,m 表示主串和模式串的长度。
public int bm(char[] a, int n, char[] b, int m) {int[] bc = new int[SIZE]; // 记录模式串中每个字符最后出现的位置generateBC(b, m, bc); // 构建坏字符哈希表int[] suffix = new int[m];boolean[] prefix = new boolean[m];generateGS(b, m, suffix, prefix);int i = 0; // j 表示主串与模式串匹配的第一个字符while (i <= n - m) {int j;for (j = m - 1; j >= 0; --j) { // 模式串从后往前匹配if (a[i+j] != b[j]) break; // 坏字符对应模式串中的下标是 j}if (j < 0) {return i; // 匹配成功,返回主串与模式串第一个匹配的字符的位置}int x = j - bc[(int)a[i+j]];int y = 0;if (j < m-1) { // 如果有好后缀的话y = moveByGS(j, m, suffix, prefix);}i = i + Math.max(x, y);}return -1;
}// j 表示坏字符对应的模式串中的字符下标 ; m 表示模式串长度
private int moveByGS(int j, int m, int[] suffix, boolean[] prefix) {int k = m - 1 - j; // 好后缀长度if (suffix[k] != -1) return j - suffix[k] +1;for (int r = j+2; r <= m-1; ++r) {if (prefix[m-r] == true) {return r;}}return m;
}

KMP算法

【C++】算法集锦(10)通俗讲kmp算法

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

量化股票查询代码是什么?

量化股票查询代码是什么&#xff1f;接下来用一些代码来分析一下&#xff0c;如下&#xff1a; 做空95&#xff1a;HHV((HIGHLOWOPEN2*CLOSE)/5H-L,5),COLORBLUE;做空68: HHV((HIGH-LOWOPEN2*CLOSE)/5*2-L,5),COLORRED&#xff1b; 平衡点&#xff1a;LLV((HIGHLOWOPEN2*CLOSE…

voipdiscount免费拨打全球电话(无需手机注册)

我测试过了的&#xff0c;能给我手机打通&#xff0c;我也给无题打了的感觉还不错。现推荐给大家&#xff01; voipdiscount免费拨打全球电话&#xff08;无需手机注册&#xff09;通话效果极好到www.voipdiscount.com下载一个软件voipdiscount,申请一个用户&#xff08;不需手…

企业使用虚拟码号的优势!

其实用不用隐私码号&#xff0c;或者怎么用隐私码号&#xff0c;是和企业的基本业务场景有关的。我们在这将近5年的服务过程中&#xff0c;遇上的行业千差万别&#xff0c;需求也是完全不同。如果非要总结一些优势的话&#xff0c;那么简单的做个应用场景分类。 隐私码号&#…

VOS网络电话如何注册IMS

IMS注册需要IMS方提供账号的注册信息 比如 用户名称&#xff1a;862584372919 认证密码&#xff1a;123456 服务器地址&#xff1a;ims.jx.chinamobile.com 认证用户&#xff1a;862584372919 SIP代理&#xff1a;172.16.5.144 第一步: 在vos的业务管理—>注册管理中按下图…

趣图:程序员假发攻略

&#xff08;给程序员的那些事加星标&#xff0c;每天看趣图&#xff09; 15 号字 ↓↓↓ (漫画原作者&#xff1a;tango2010 投稿&#xff1a;遇见) 往期趣图&#xff08;点击下方图片可跳转阅读&#xff09; 关注「程序员的那些事」加星标&#xff0c;不错过趣图 &#xff0…

老大“秃”伤悲的年轻人,正靠假发维持最后的体面

本文转载自虎嗅网 如今90后的潮流&#xff0c;已经逐渐让人看不懂了。 现在见面第一句话都不是“今天你基金绿了吗&#xff1f;”“今天你cp发糖了吗&#xff1f;”&#xff0c;而是&#xff1a; “你今天戴的是假发吗&#xff1f;” 随着越来越多的90后涌入脱发大军&#…

计算机毕业设计php假发销售商城网站(源码+系统+mysql数据库+Lw文档)

项目介绍 假发销售网站使用php,mysql实现了如用户注册、用户登录、假发商品的预览查询、对假发商品的购买通过购物车实现、可进入留言本留言等等&#xff0c;从而实现了网站与客户之间的交流和沟通。 功能&#xff1a;客户功能和管理员功能两个部分。 设计题目&#xff1a;假…

c语言链表假发管理系统,C语言链表关键字检索

满意答案 a_xman 2014.09.20 采纳率&#xff1a;58% 等级&#xff1a;9 已帮助&#xff1a;1813人 /**************************** 包括头文件 *****************************/ #include #include /***************************** 函数声明 *****************************…

ios图形之矩阵操作

1 - (void)drawRect:(CGRect)rect2 {3 // 画四边形4 CGContextRef ctx UIGraphicsGetCurrentContext();5 6 // 保存上下文7 CGContextSaveGState(ctx);8 9 // 注意:设置矩阵操作必须在添加绘图信息之前 10 CGContextRotateCTM(ctx, M_PI_4); …

深度:数据解读百亿规模中老年假发市场发展趋势 国内外假发上市公司发展经验

在对中老年群体消费需求与消费心理进行持续深入研究过程中&#xff0c;AgeClub发现对脱发问题严重的中老年人来说&#xff0c;假发是最好的改变外表形象的选择&#xff0c;拥有巨大市场需求和发展潜力。 据中国健康促进与教育协会2016年公布的“中国脱发人群调查”&#xff0c…

怎么在php文件插入背景图片,怎么给视频文件添加背景图片?将视频放在图片上面播放...

都说“清明时节雨纷纷”&#xff0c;明天就是清明节了&#xff0c;小编抬头望望天空可真是没有一丝丝要下雨的节奏啊。清明节放假&#xff0c;大家有么有计划回家呢~反正小编是没计划的&#xff0c;小编的妈妈告诉小编说“你别回来除人……”&#xff0c;除人在小编家乡那边的意…

服务器图片加载慢_张云雷开工拍杂志,昕薇服务器一定优化好别崩,手机被卡已三回...

美好的九月第一天&#xff0c;也是周末&#xff0c;张云雷发微博&#xff0c;今天你们开学我开工&#xff0c;还没下班转场中&#xff0c;辫儿哥哥有才华呀&#xff0c;说话都一套一套的押韵。 他说摩羯座太难了&#xff0c;难不难不知道&#xff0c;就看出摩羯座的张云雷颜值要…

二元函数图像生成器_谷歌程序员自制秃头生成器:一键get张东升同款发型,今天你脱发了吗?...

文章来源于微信公众号&#xff1a;机器之心 作者 |Synced 原文链接&#xff1a;请点击 文章仅用于学习交流&#xff0c;如有侵权请联系删除 头可断&#xff0c;发型不能乱。 最近有一个男人的名字实在太火了&#xff0c;他叫「张东升」&#xff1b;比他本人更出名的&#xff0c…

时标网络图

认识时标网络图 时标网络图可解决的问题 一、 直接看关键路径、自由时差和总时差 自由时差&#xff1a;不影响任何紧后活动最早开始时间下本活动可推迟时间 总时差关键路径时长-活动所在最长路径 二、资源平滑-移动活动&#xff0c;通过浮动时间优化资源需求【重要】 三、计算…

假发重回颜值赛道,假发经济起风?

配图来自Canva可画 年轻人的爱美是从头到脚的精致装扮&#xff0c;谁能忍受自己拥有张东升同款秃头&#xff1f;即使是一丝一毫的发际线上移都会让人愤懑不已。看过张东升戴假发前后的样子&#xff0c;大家不得不相信头发对颜值的重要性。而一众明星又带火了挂耳染、漫画刘海等…

基于PHP假发销售商城网站

假发销售网站使用php,mysql实现了如用户注册、用户登录、假发商品的预览查询、对假发商品的购买通过购物车实现、可进入留言本留言等等&#xff0c;从而实现了网站与客户之间的交流和沟通。 功能&#xff1a;客户功能和管理员功能两个部分。 设计题目&#xff1a;假发销售网站…

多图 | Java 程序员必备的一些流程图

1.spring的生命周期2.TCP三次握手&#xff0c;四次挥手3.线程池执行流程图4.JVM内存结构5.Java内存模型6.springMVC执行流程图7.JDBC执行流程8.spring cloud组件架构9.dubbo 调用 整理了一些Java基础流程图/架构图&#xff0c;做一下笔记&#xff0c;大家一起学习。 1.spring的…

微信整人假红包图片_微信假红包图片生成器,假红包生成器微信(玩别人没商量)...

你要记住&#xff0c;无论最后我们疏远成什么样子&#xff0c;一个红包最能回到当初 。这段话在朋友圈很是流行&#xff0c;而且现在大家的聊天方式就是一言不合就发红包&#xff0c;惹女朋友生气了&#xff0c;发个红包就好了&#xff0c;亲朋好友的聊天群里&#xff0c;发个红…

2021年中国假发制品行业现状分析:颜值经济促进需求量[图]

一、假发分类 假发制品是通过人造技术制造而成的头发&#xff0c;用于装饰的饰品。可供秃头或头发稀少的人作头饰戴用&#xff0c;或作为戏装、官员或专业人员装束或时髦装饰的一部分。 假发分类 资料来源&#xff1a;智研咨询整理 二、假发制品销售收入 假发属于轻工业制造…

【探花交友DAY 07】即时通讯模块的实现

1. 即时通讯模块设计 1.1 什么是即时通讯 即时通讯简称IM&#xff08;Instant Message&#xff09;&#xff0c;是指能够即时地发送和接受互联网消息等服务。常见的即时通讯服务有QQ&#xff0c;微信等。在我们探花交友项目中&#xff0c;也运用到了即时通讯技术。两个陌生人…