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

(一)前言

所谓的字符串匹配就是在一个长字符串(可称文本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类时做出某些设计决策的背景信息。 本文的“…

计算机网络第三章知识网络,计算机基础教案第三章计算机网络基础知识教案

计算机 基础 教案一、网络基础知识1、计算机网络的概念计算机网络是指将分布在不同地理位置的具有独立功能的多台计算机用通信设备连接起来&#xff0c;并配以相应的网络软件&#xff0c;以实现信息传递和资源共享。计算机网络的三个主要组成部分&#xff1a;(1)主机(2)通信网络…

plc secs通讯协议_SECS/GEM解决方案:PLC与MES间的通讯

符合SEMI E4, E5, E30, E37 的 SECS/GEM通讯方案遵循 SEMI 人机交互设计&#xff0c;提供触摸屏支持让你触手可及。毫米级的响应&#xff0c;让设备行云流水般流畅。我们为你快速搭建PLC与MES之间的SECS/GEM桥梁SECS/GEM介绍SECS/GEM定义半导体生产设备与主机之间的通讯关系&am…

计算机程序和系统股票走势分析,证券走势指标匹配分析系统的设计与实现

摘要&#xff1a;随着计算机技术在证券分析领域的广泛应用,利用计算机对股票数据进行分析,已经成为股票走势技术分析方法的必然选择.经过历代伟大的证券分析师不懈的研究,已经总结出多种根据股票历史数据计算出的指标,在证券分析领用运用计算机技术来提高投资收益率已经成为各大…

security放行 spirng_Spring Security配置

第一步&#xff0c;空Spring Boot环境。暂时不添加了Spring Security依赖。第二步&#xff0c;确保项目能够正常运行。启动启动项 Application.javaimport org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.EnableAutoConfiguration…

Cactoos中的面向对象的声明式输入/输出

Cactoos是一个面向对象的Java原语库&#xff0c; 我们几周前才开始使用它。 目的是为JDK&#xff0c;Guava&#xff0c;Apache Commons等提供一种干净且更具声明性的替代方案。 我们不是使用静态过程&#xff0c;而是使用对象的使用方式&#xff0c;而是使用对象。 让我们看看输…

计算机研发部门职责,计算机研发岗位职责

计算机视觉研发员 •负责计算机视觉相关的技术研发工作,包括但不限于:人脸识别、物体检测与分类、静态图像或视频分类与分析、图像质量评价、图像处理等•负责计算机视觉方向前沿问题的研究,结合未来实际应用场景,提供技术解决方案•负责完成相关技术的研究项目申请、学术论文发…

vue中请求接口怎么封装公共地址_vue请求接口的封装

import api from ./api;import request from./request;//获取url上的rest参数&#xff0c;返回参数列表 /{userId}/{roleId} > [userId, roleId]functiongetUrlParams(url) {return (url.match(/\{(\w)\}/g) || []).map(param > /\{(\w)\}/.exec(param)[1]);}/** 创建一个…

java实现迷你计算机,用JAVA写一个迷你编辑器.doc

用JAVA写一个迷你编辑器用JAVA编写一个迷你编辑器WINDOWS的记事本程序是非常方便的一个文字处理工具&#xff0c;用它来编辑纯文本文件快捷而灵巧。我用JAVA写了一个编辑器程序&#xff0c;模仿“记事本”的功能。这不是为了替代记事本&#xff0c;而是因为下列两个目的&#x…

cypress测试脚本_Cypress 自动化测试学习使用

安装mkdir cypress-startnpm install# 进入创建的项目目录cd /your/project/pathcd cypress-startnpm install cypress --save-devyarn addcd /your/project/pathcd cypress-startyarn add cypress --dev打开运行cpress./node_modules/.bin/cypress open或者使用npm bin$(npm b…

hadoop综述_Hadoop书籍赠品–综述

hadoop综述各位极客&#xff0c; Packt Publishing关于Apache Hadoop 的书籍赠品已经结束。 您可以在这里找到比赛的原始帖子。 获奖者 将会获得这本书奖的6位幸运获奖者是&#xff08;姓名出现在他们的电子邮件中&#xff09;&#xff1a; Hadoop真实世界解决方案食谱 塞…

便捷式计算机无线功能按钮,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; 。” 这…

矩阵相乘的strassen算法_矩阵乘法的Strassen算法+动态规划算法(矩阵链相乘和硬币问题)...

矩阵乘法的Strassen这个算法就是在矩阵乘法中采用分治法&#xff0c;能够有效的提高算法的效率。先来看看咱们在高等代数中学的普通矩阵的乘法两个矩阵相乘上边这种普通求解方法的复杂度为: O(n3)也称之为暴力求解或者朴素求解这是暴力求解的代码&#xff0c;三重循环&#xff…

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

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

springboot 注解动态赋值_SpringBoot 使用 @Value 注解读取配置文件给静态变量赋值

1、application.properties 配置文件CxU免费资源网mail.usernamexue163.commail.passwordxuemail.hostsmtp.163.commail.smtp.authtrue2、给普通变量赋值&#xff0c;直接在变量上添加 Value 注解CxU免费资源网import org.springframework.beans.factory.annotation.Value;publ…

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

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

ceph与hdfs的比较_分布式存储中HDFS与Ceph两者的区别是什么,各有什么优势?

过去两年&#xff0c;我的主要工作都在Hadoop这个技术栈中&#xff0c;而最近有幸接触到了Ceph。我觉得这是一件很幸运的事&#xff0c;让我有机会体验另一种大型分布式存储解决方案&#xff0c;可以对比出HDFS与Ceph这两种几乎完全不同的存储系统分别有哪些优缺点、适合哪些场…

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

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