# 字符串从右往左查找_字符串匹配(搜索,查找)算法

(一)前言

所谓的字符串匹配就是在一个长字符串(可称文本T)中找一个短字符串(可称模式P),看长字符串中是否存在短字符串,若存在则返回出现的第一个位置,若不存在则返回一个标记。字符串搜索算法有很多,比较知名的自然是大名鼎鼎Knuth-Morris-Pratt 算法(简称 KMP)和Boyer-Moore(简称BM)。关于这两个算法的实现比较复杂,需要很多的前置知识,不在这里长篇大论,有兴趣的同学,可自行搜索。

今天给大家介绍一个相对高效且简单的Horsepool算法,Horsepool算法是Boyer-Moore算法的简化版本,为了方便理解Horsepool算法,我们先从朴素字符串匹配算法谈起。

(二)朴素(暴力)字符串匹配算法

先看朴素的字符串匹配算法的过程:

e54ed66e8e58fff33ee9274105fe0321.png算法规则:用i,j表示两字符串正在比较的字符位置。若长字符串与短字符串该位置字符匹配,则继续比较二者后面的字符,即i加1,j加1。不匹配,分别回溯i,j。这个算法非常朴素,通常性能极差。最坏情况举例:aaaaaaaab和aaab匹配,需要重复比较字符多次。

朴素搜索Python实现:

# txt 长字符串,pat 短字符串def forceSearch(txt, pat):    M = len(txt)    N = len(pat)    for i in range(M-N+1):        for j in range(N):            if txt[i+j]!=pat[j]:                break        else:            return i    return 

(三)Horspool算法

Horspool算法把短字符串(以下简称模式P)与长字符串(以下简称文本T)的开头字符对齐,从模式P的最后一个字符开始比较,如果尝试比较失败了,它把模式P向后移。每次尝试过程中比较是从右到左的。

假设对齐后文本T中最后一个对齐字符为X(代表任意字符),Horspool算法根据X的不同情况来确定移动距离(朴素算法每次不匹配只右移一位),无论X是否和模式的最后一个字符相匹配,一般来说,会存在下面四种情况:

fcce097c966514ac81daff5460c48c6f.png

情况1,如上图所示,对齐后,文本T中最后一个字符对齐X为o,与模式P最后一个字符g不匹配,且模式P中不存在X(也就是字母o),模式P的移动长度就是它的全部长度,移到所示的位置。

9b3dc2c80256c0fae92921b2211a3580.png

情况2,如上图所示,对齐后,文本T的最后一个对齐字符X为e,恰好和模式P最后一个字符匹配。但是从右向左比较时,有字符不匹配,比如此时的oa不匹配。由于模式P中只包含一个字符X(也就是e),模式P的移动长度就是它的全部长度,移到所示的位置。

4f77ce282876160fc6ef0dc71002971f.png情况3,如上图所示,对齐后,文本T的最后一个对齐字符X为a,与模式P最后一个字符g不匹配。移动时应该把模式P中最右边的X(a)和文本中的X(a)对齐。

a3457fddf78f7c98cfd62e68dbfb75a2.png

情况4,如上图所示,对齐后,文本T的最后一个对齐字符X为a,与模式P最后一个字符a匹配,但是从右向左比较时,有字符不匹配,比如此时的ni不匹配。移动时,应把模式P除X(a)外,最右边字符X(a)和文本T中的X(a)对齐。

综上所述,比起朴素算法每次总是移动一个位置,从右到左的字符比较使模式不匹配时可以移动得更远。然而,如果在每次尝试时都必须检查模式P中的每个字符来确定移动距离,它的优势也会丧失殆尽。我们可以预先算出遇到某个字符要移动的距离,并把它存在一个表中。

示例如下,对于模式BARBER,移动距离如下表所示:

4b30fda0ebfa747e831b4fb73d1528ed.png

这里对字符A,B做一下解释,方便还没有理解的同学,加深理解。

若对齐后,文本T的最后一个对齐字符X为A,A与R不匹配,BARBER,A与结尾处R字符距离为4。

若对齐后,文本T中最后一个对齐字符X为B,B与R不匹配,BARBER,最右边B与结尾处R字符距离为2。

若对齐后,文本T中最后一个对齐字符X不在模式P中,则移动距离为模式P长度6。

Horspool算法Python实现:

def horspool(txt,pat):    n = len(txt)    m = len(pat)    table = [m]*96 #ascii中可打印字符有96,且前32为控制字符    for i in range(m - 1):        table[ord(pat[i]) - 32 ] = m -1 - i        #从左至右扫描模式,相同字符的最后一次改写恰好是该字符在模式串的最右边    i = m - 1    while i <= n - 1:        k = 0        while k <= m-1 and pat[m - 1 - k] == txt[i - k]:            k += 1                       #向左比较下一个字符        if k == m:            return  i - m + 1            #匹配成功返回索引        else:            i += table[ord(txt[i]) - 32] #根据表格移动模式串    return -1

(四)参考文献

[1]https://blog.csdn.net/khwkhwkhw/article/details/51288502

[2]https://www.runoob.com/python/python-for-loop.html

[3]https://www.asklib.com/view/fbef10420ab8.html

[4]https://blog.csdn.net/gilzhy/article/details/16803993

[5]https://ethsonliu.com/2018/04/kmp.html

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

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

相关文章

html5按钮样式具有子项目,如何使用HTML5+css3制作出12种常用的按钮开关样式(附完整代码)...

现如今前端网页的开发越来越注重设计感&#xff0c;这些设计感更体现在细节处&#xff0c;今天向大家具体介绍一下各式各样的开关按钮是如何使用HTML5css3制作出来的&#xff0c;希望可以帮到大家。使用HTML5css3制作按钮开关的原理根据设计的要求填充各种颜色。按钮开关的形状…

Java命令行界面(第17部分):jw-options

JavaWorld文章处理Java中的命令行参数&#xff1a; Matthias Laux博士关闭的案例介绍了一个基于Java的简单库&#xff0c;用于处理命令行参数 &#xff0c;在本文中我将其称为jw-options 。 被引用的文章提供了有关为何在构造Options类时做出某些设计决策的背景信息。 本文的“…

便捷式计算机无线功能按钮,TP-Link TL-MR13U便携式无线路由器Client模式设置

本文介绍了TP-Link TL-MR13U便携式无线路由器&#xff0c;在“客户端模式(Client)”下的设置方法。TL-MR13U工作在“客户端模式(Client)”时&#xff0c;主要作用是用来接收无线WiFi信号&#xff0c;把无线WiFi信号转换为有线网络&#xff0c;实现让台式电脑上网。TP-Link TL-M…

Java命令行界面(第6部分):JOpt简单

JOpt Simple的主页将这个基于Java的库称为“用于解析命令行选项的Java库&#xff0c;例如您可能传递给调用javac的Java库&#xff0c;”该Java库试图“使用POSIX getopt&#xff08;&#xff09;的命令行选项语法&#xff09;和GNU getopt_long&#xff08;&#xff09; 。” 这…

计算机c盘哪些东西可以清理,细说电脑c盘哪些文件可以删除

有些网友反映&#xff0c;自己看C盘里的文件太多了&#xff0c;电脑又太卡&#xff0c;情急之下就把里面的东西删掉了&#xff0c;现在系统都不能用了。为了避免大家再入这个坑&#xff0c;我给大家讲一下哪些是C盘里的无用文件&#xff0c;并且删除后不会影响系统使用C盘是指电…

软件测试度量计算方法有哪些,软件测试度量(三)

进度差异趋势6.4.3 范围变化(SC)这个指标指出如何固定测试范围。下面总范围 以前的范围 新范围&#xff0c;如果范围扩大的话总范围 以前的范围 - 新范围&#xff0c;如果范围缩小的话一个发布版本范围变化趋势7、结论度量是评估的重要组成部分以及任何业务改进的基础。是应…

使用带有OAuth的Spring Security保护资源

1.简介 在本教程中&#xff0c;我们将研究如何使用Spring Security和OAuth来基于路径模式&#xff08; / api / ** &#xff09;保护服务器上的管理资源。 我们配置的另一个路径模式&#xff08; / oauth / token &#xff09;将帮助已配置的授权服务器生成访问令牌。 请注意&a…

openjpa_OpenJPA:内存泄漏案例研究

openjpa本文将提供完整的根本原因分析详细信息以及解决影响Oracle Weblogic Server 10.0生产环境的Java堆内存泄漏&#xff08;Apache OpenJPA泄漏&#xff09;的方法。 这篇文章还将演示在管理javax.persistence.EntityManagerFactory生命周期时遵循Java Persistence API最佳实…

美国凯斯西储大学计算机硕士专业怎么样,在凯斯西储大学读硕士大约需要多少花费?...

凯斯西储大学是美国著名大学之一&#xff0c;始建于1826年&#xff0c;坐落于俄亥俄州的克里夫兰&#xff0c;是一所以独立研究闻名的世界顶级私立大学&#xff0c;美国一级国家级大学。美国作为当今世界留学费用最高的国家之一&#xff0c;费用问题是所有赴美留学的学生都非常…

win7如何修改dns服务器地址,Win7系统DNS怎么设置?Win7系统DNS设置方法

Win7系统DNS怎么设置?众所周知&#xff0c;DNS地址是一个域名服务器地址&#xff0c;它可以把用户的网站地址解析成IP地址。如果这个服务器出现问题&#xff0c;可能就上不了网了。我们在使用Win7系统的时候&#xff0c;就是因为域名解析服务器不能将要访问的域名解析为正确的…

密钥文件登录服务器,密钥文件登录云服务器

密钥文件登录云服务器 内容精选换一换远程桌面协议(Remote Desktop Protocol&#xff0c;RDP)&#xff0c;是微软提供的多通道的远程登录协议。本节为您介绍如何使用RDP文件远程登录Windows弹性云服务器。从管理控制台下载的RDP文件对应唯一的云服务器&#xff0c;当前RDP文件命…

一个网站服务器有多少个ip,一个服务器可以有多少个ip地址

一个服务器可以有多少个ip地址 内容精选换一换华为云帮助中心&#xff0c;为用户提供产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题、视频帮助等技术文档&#xff0c;帮助您快速上手使用华为云服务。会话保持&#xff0c;指负载均衡器可以识别客户与服…

jbpm小项目测试_尝试使用jBPM Console NG(测试版)

jbpm小项目测试大家好&#xff01; 这是有关jBPM Console NG的另一篇文章。 经过6个月的辛苦工作&#xff0c;我很高兴为开发人员社区撰写这篇文章&#xff0c;以进行尝试。 在这篇文章中&#xff0c;我将解释如何从源代码构建应用程序。 这背后的主要思想是知道如何在测试过程…

用友数据库服务器如何修改,用友u8数据库服务器怎么设置

用友u8数据库服务器怎么设置 内容精选换一换本章介绍如何在管理控制台购买GaussDB(for openGauss)实例&#xff0c;并通过内网使用弹性云服务器连接GaussDB(for openGauss)实例。GaussDB(for openGauss)提供gsql工具帮助您在命令行下连接数据库&#xff0c;您需要提前创建一台弹…

hibernate批量查询_使用Hibernate批量获取

hibernate批量查询如果需要从Java处理大型数据库结果集&#xff0c;则可以选择JDBC&#xff0c;以提供所需的低级控制。 另一方面&#xff0c;如果您已在应用程序中使用ORM&#xff0c;则回退到JDBC可能会带来一些额外的麻烦。 在导航域模型时&#xff0c;您将失去诸如乐观锁定…

Java 9迁移指南:七个最常见的挑战

我确定您已经听说过更新到Java 9并不是一件容易的事&#xff0c;甚至可能是不兼容的更新&#xff0c;而且对于大型代码库而言&#xff0c;迁移毫无意义。 这样做之后&#xff0c;我迁移了一个相当大的旧代码库&#xff0c;我可以告诉你&#xff0c;这还不错。 比碰到Java 8确实…

nuxt sass 全局变量的问题_Sass入门教程

SASS(Syntactically Awesome Stylesheet)是一个CSS预处理器&#xff0c;有助于减少CSS的重复&#xff0c;节省时间。 它是更稳定和强大的CSS扩展语言描述文档的风格结构。sass中文网而且Sass算是CSS的超集&#xff0c;它100%兼容CSS的语法&#xff0c;所有在 CSS 中正常工作的代…

用C语言实现优先级排序和MATLABsort函数的比较

为了实现对两个数组进行优先级排序,用c语言有两种实现方法, 一是需要对两个数组进行排序,然后对排序后的坐标再排序,(求最小值是我自己需要) 二是直接寻找数组排序后的元素坐标,调用qsort函数进行排序,排序后的数组会存放在原数组中,那么就有两种寻找坐标,一是寻找…

造成内存泄漏_如何造成内存泄漏

造成内存泄漏这将是一个相当邪恶的职位-当您确实希望使某人的生活陷入困境时&#xff0c;您将在谷歌上搜索。 在Java开发领域&#xff0c;内存泄漏只是您在这种情况下会引入的错误类型。 为您的受害者保证几天甚至几周的办公室不眠之夜。 我们将在这篇文章中描述两次泄漏。 两…

通过Java,Spring Boot应用程序将Gmail用作SMTP服务器

Gmail用户可以使用Gmail的SMTP服务器smtp.gmail.com从其Spring Boot应用程序发送电子邮件。 为此&#xff0c;让我们在应用程序中进行一些设置&#xff1a; 在application.properties文件中提供SMTP连接属性&#xff1a; spring.mail.hostsmtp.gmail.com spring.mail.username…