当前位置: 首页 > news >正文

字符串匹配 扩展KMP BMSunday

复杂度都是O(n)

 

 扩展1:BM算法

    KMP的匹配是从模式串的开头开始匹配的,而1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法:Boyer-Moore算法,简称BM算法。该算法从模式串的尾部开始匹配,且拥有在最坏情况下O(N)的时间复杂度。在实践中,比KMP算法的实际效能高。

    BM算法定义了两个规则:

  • 坏字符规则:当文本串中的某个字符跟模式串的某个字符不匹配时,我们称文本串中的这个失配字符为坏字符,此时模式串需要向右移动,移动的位数 = 坏字符在模式串中的位置 - 坏字符在模式串中最右出现的位置。此外,如果"坏字符"不包含在模式串之中,则最右出现位置为-1。
  • 好后缀规则:当字符失配时,后移位数 = 好后缀在模式串中的位置 - 好后缀在模式串上一次出现的位置,且如果好后缀在模式串中没有再次出现,则为-1。

    下面举例说明BM算法。例如,给定文本串“HERE IS A SIMPLE EXAMPLE”,和模式串“EXAMPLE”,现要查找模式串是否在文本串中,如果存在,返回模式串在文本串中的位置。

    1. 首先,"文本串"与"模式串"头部对齐,从尾部开始比较。"S"与"E"不匹配。这时,"S"就被称为"坏字符"(bad character),即不匹配的字符,它对应着模式串的第6位。且"S"不包含在模式串"EXAMPLE"之中(相当于最右出现位置是-1),这意味着可以把模式串后移6-(-1)=7位,从而直接移到"S"的后一位。

    2. 依然从尾部开始比较,发现"P"与"E"不匹配,所以"P"是"坏字符"。但是,"P"包含在模式串"EXAMPLE"之中。因为“P”这个“坏字符”对应着模式串的第6位(从0开始编号),且在模式串中的最右出现位置为4,所以,将模式串后移6-4=2位,两个"P"对齐。

    3. 依次比较,得到 “MPLE”匹配,称为"好后缀"(good suffix),即所有尾部匹配的字符串。注意,"MPLE"、"PLE"、"LE"、"E"都是好后缀。

 

    4. 发现“I”与“A”不匹配:“I”是坏字符。如果是根据坏字符规则,此时模式串应该后移2-(-1)=3位。问题是,有没有更优的移法?

    5. 更优的移法是利用好后缀规则:当字符失配时,后移位数 = 好后缀在模式串中的位置 - 好后缀在模式串中上一次出现的位置,且如果好后缀在模式串中没有再次出现,则为-1。
    所有的“好后缀”(MPLE、PLE、LE、E)之中,只有“E”在“EXAMPLE”的头部出现,所以后移6-0=6位。
    可以看出,“坏字符规则”只能移3位,“好后缀规则”可以移6位。每次后移这两个规则之中的较大值。这两个规则的移动位数,只与模式串有关,与原文本串无关。

    6. 继续从尾部开始比较,“P”与“E”不匹配,因此“P”是“坏字符”,根据“坏字符规则”,后移 6 - 4 = 2位。因为是最后一位就失配,尚未获得好后缀。

 

    由上可知,BM算法不仅效率高,而且构思巧妙,容易理解。

 
 
 

 扩展2:Sunday算法

  • Sunday算法是从前往后匹配,在匹配失败时关注的是文本串中参加匹配的最末位字符的下一位字符。
    • 如果该字符没有在模式串中出现则直接跳过,即移动位数 = 匹配串长度 + 1;
    • 否则,其移动位数 = 模式串中最右端的该字符到末尾的距离+1。

    下面举个例子说明下Sunday算法。假定现在要在文本串"substring searching algorithm"中查找模式串"search"。

    1. 刚开始时,把模式串与文本串左边对齐:
substring searching algorithm
search
^
    2. 结果发现在第2个字符处发现不匹配,不匹配时关注文本串中参加匹配的最末位字符的下一位字符,即标粗的字符 i,因为模式串search中并不存在i,所以模式串直接跳过一大片,向右移动位数 = 匹配串长度 + 1 = 6 + 1 = 7,从 i 之后的那个字符(即字符n)开始下一步的匹配,如下图:

substring searching algorithm
    search
    ^
    3. 结果第一个字符就不匹配,再看文本串中参加匹配的最末位字符的下一位字符,是'r',它出现在模式串中的倒数第3位,于是把模式串向右移动3位(r 到模式串末尾的距离 + 1 = 2 + 1 =3),使两个'r'对齐,如下:
substring searching algorithm
      search
       ^

    4. 匹配成功。

    回顾整个过程,我们只移动了两次模式串就找到了匹配位置,缘于Sunday算法每一步的移动量都比较大,效率很高。完。

 
 
还发现了一个厉害的库函数strstr
包含在cstring里
char *pos = strstr(*str1, *str2);返回的是地址
如果str2是str1的子串 返回str1中的地址 否则是null

 

转载于:https://www.cnblogs.com/wyboooo/p/9643438.html

相关文章:

  • linux系统下配置Django虚拟环境的一些总结
  • pwntools 文档学习
  • Notes 20180308 : 语句
  • 软件工程阅读笔记一
  • Servlet中forward和redirect的区别(转)
  • (1)常见O(n^2)排序算法解析
  • 性能测试---不同视角看性能和相关术语
  • java ee5的新特性
  • [LuoguP1141]01迷宫
  • webpack学习笔记1
  • POJ2187 旋转卡壳 求最长直径
  • 《Java并发编程的艺术》--Java中的锁
  • win10 vs2015源码编译tesseract4.0
  • Go语言备忘录(2):反射的原理与使用详解
  • ubuntu16.04 更换源
  • 2017届校招提前批面试回顾
  • AzureCon上微软宣布了哪些容器相关的重磅消息
  • JavaScript设计模式之工厂模式
  • Js基础——数据类型之Null和Undefined
  • JS学习笔记——闭包
  • MySQL常见的两种存储引擎:MyISAM与InnoDB的爱恨情仇
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • PHP的类修饰符与访问修饰符
  • Vue组件定义
  • 对超线程几个不同角度的解释
  • 基于游标的分页接口实现
  • 计算机在识别图像时“看到”了什么?
  • 聊聊sentinel的DegradeSlot
  • 软件开发学习的5大技巧,你知道吗?
  • 网络应用优化——时延与带宽
  • 追踪解析 FutureTask 源码
  • 自动记录MySQL慢查询快照脚本
  • 基于django的视频点播网站开发-step3-注册登录功能 ...
  • 移动端高清、多屏适配方案
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​渐进式Web应用PWA的未来
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • (02)vite环境变量配置
  • (bean配置类的注解开发)学习Spring的第十三天
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (论文阅读23/100)Hierarchical Convolutional Features for Visual Tracking
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (转)PlayerPrefs在Windows下存到哪里去了?
  • (转)大型网站架构演变和知识体系
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .NET 应用启用与禁用自动生成绑定重定向 (bindingRedirect),解决不同版本 dll 的依赖问题
  • .NET设计模式(11):组合模式(Composite Pattern)
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • .net中调用windows performance记录性能信息
  • ??myeclipse+tomcat
  • @modelattribute注解用postman测试怎么传参_接口测试之问题挖掘
  • @Query中countQuery的介绍
  • [ solr入门 ] - 利用solrJ进行检索
  • [ 隧道技术 ] cpolar 工具详解之将内网端口映射到公网