BM串匹配算法
串匹配算法最常用的情形是从一篇文档中查找指定文本。需要查找的文本叫做模式串,需要从中查找模式串的串暂且叫做查找串吧。
BM算法好后缀规则
公式:
对于长度为m的模式串P,在i处失配时,模式串向前滑动的距离next[i]等于:
next[i]= { 1; i = m;
i-k+1; 存在最大的K (1 <= k <= i),使得 PkPk+1..Pk+m-i-1 == Pi+1Pi+2..Pm 且Pk-1 != Pi =>case 1
m-k; 存在最大的K (1 <= k <= m-i),使得 P1P2..Pk == Pm-k+1..Pm-1Pm =>case 2
m; 其他情况; =>case 3 }
下面是图示解析(图来自http://www.tuicool.com/articles/nqqE3uU,下面是少有图绘制正确的解析):
三种情形一张图表示
可以看出好后缀规则和kmp算法有点像,kmp是从左向右有自匹配的话能减少一些比较,bm算法是从右向左有自匹配的话能减少一些比较。下面代码的思路就是先求出自匹配长度,再求移动距离。好后缀规则的代码,是Python的,直接从源代码执行的语言用来写算法很方便。这里求自匹配的代码是优化过的,优化算法参考Boyer- Moore算法百度百科。
- def suffix(s):
- """
- suff[i] = k, the length of the longest suffix of s[:i](the sub string of s ending at i)
- that matches a suffix of s (the sub string of s ending at len(s)-1)
- """
- m=len(s)
- g = m-1
- suff = {}
- suff[g]=m
- for i in range(m-2,-1,-1):
- if(i>g and suff[m-1-f+i]<i-g):
- suff[i] = suff[m-1-f+i]
- else:
- if(i<g):
- g = i
- f = i
- while(g>=0 and s[g]==s[m-1-f+g]):
- g-=1
- suff[i] = f - g
- return suff
- def PreBmGs(s):
- m = len(s)
- suff = suffix(s)
- bmGs = {}
- for i in range(0,m,1):
- bmGs[i] = m
- for i in range(m-1,-1,-1):
- if(i+1 == suff[i]):
- for j in range(0,m-1-i,1):
- if(m == bmGs[j]):
- bmGs[j] = m-1-i;
- for i in range(0,m-1,1):
- bmGs[m - 1 - suff[i]] = m - 1 - i;
- return bmGs;
坏字符规则
当模式串与查找串在某个位置失配,查找串失配位置的字符叫做坏字符。单独能实现匹配的坏字符规则是:将模式串失配位置左侧最靠近失配位置的坏字符和查找串的失配位置对齐;如果模式串失配位置左侧不包含坏字符,那么将模式串头部对齐坏字符下一个(右侧)位置。实际上的坏字符规则比这个要简单,模式串最右侧的坏字符和查找串的失配位置对齐;如果模式穿不包含坏字符,那么将模式串头部对齐坏字符下一个(右侧)位置。下图的公示就包含了这两种情况了。
由于坏字符规则不是在模式串失配位置左侧字串中应用的,所以会出现将模式串向回移动的情况。由于有好后缀规则,这种失效的情况可以被避免。
- def PreBmBc(s):
- m = len(s)
- bmBc = {}
- for i in range(0,m-1,1):
- bmBc[s[i]] = i;
- return bmBc;
BM算法匹配源码
- def BoyerMoore(s,p):
- m = len(p)
- n = len(s)
- bmBc = PreBmBc(p)
- bmGs = PreBmGs(p)
- j = 0
- while(j <= n-m):
- i = m-1
- while(i>=0 and p[i]==s[j+i]):
- i -= 1
- if(i < 0):
- 'Find, next fint start at j+bmGs[0]'
- return j
- else:
- bc = -1
- if(bmBc.has_key(s[j+i])):
- bc = bmBc[s[j+i]]
- j += max(bmGs[i],i-bc)
- return -1
BM算法的其他解析
http://www-igm.univ-mlv.fr/~lecroq/string/node14.html
这个地方给出的C语言代码和上面的python代码一样的方式优化了。
http://www.inf.fh-flensburg.de/lang/algorithmen/pattern/bmen.htm
这个地方给出的C代码根据上面的规则直接暴力解决。
BM串匹配算法的更多相关文章
- KMP串匹配算法解析与优化
朴素串匹配算法说明 串匹配算法最常用的情形是从一篇文档中查找指定文本.需要查找的文本叫做模式串,需要从中查找模式串的串暂且叫做查找串吧. 为了更好理解KMP算法,我们先这样看待一下朴素匹配算法吧.朴素 ...
- 串匹配算法讲解 -----BF、KMP算法
参考文章: http://www.matrix67.com/blog/archives/115 KMP算法详解 http://blog.csdn.net/yaochunnian/artic ...
- 串匹配算法之BM算法
参考资料: http://blog.csdn.net/eric491179912/article/details/6210009 http://blog.163.com/pengfeicui@ye ...
- 【数据结构】 字符串&KMP子串匹配算法
字符串 作为人机交互的途径,程序或多或少地肯定要需要处理文字信息.如何在计算机中抽象人类语言的信息就成为一个问题.字符串便是这个问题的答案.虽然从形式上来说,字符串可以算是线性表的一种,其数据储存区存 ...
- 算法 | 串匹配算法之KMP算法及其优化
主串 s:A B D A B C A B C 子串 t: A B C A B 问题:在主串 s 中是否存在一段 t 的子串呢? 形如上述问题,就是串匹配类问题.[串匹配--百度百科] 串匹配问题是一 ...
- 经典串匹配算法(KMP)解析
一.问题重述 现有字符串S1,求S1中与字符串S2完全匹配的部分,例如: S1 = "ababaababc" S2 = "ababc" 那么得到匹配的结果是5( ...
- Sunday串匹配算法 C语言实现
unsigned char * sunday( void * a_buf1, unsigned int len1, void * a_buf2, unsigned int len2 ){ unsign ...
- KMP(字符串匹配)算法
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- 算法——字符串匹配之BM算法
前言 Boyer-Moore算法是一种基于后缀匹配的模式串匹配算法(简称BM算法),后缀匹配就是模式串从右到左開始比較,但模式串的移动依旧是从左到右的.在实践中.BM算法效率高于前面介绍的<KM ...
随机推荐
- ASP.NET MVC4 WebAPI若干要点
本文仅仅是将一些可以运行无误的WebAPI示例的要点,记录下来,供自己查阅,也供刚刚学习WebAPI的读者参考之. 1.默认的API是不会过滤到action这个级别的,如果要过滤到这个级别,必须在路由 ...
- (medium)LeetCode 229.Majority Element II
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorit ...
- java7新特性 java8新特性
Java 7 的7个新特性 Java7语法新特性 JAVA8 十大新特性详解 http://www.jb51.net/article/48304.htm
- 关于Android studio 相对 eclipse 优点
优点:说法一 1.Google推出的,这个是它的最大优势,Android Stuido是Google推出,专门为Android"量身订做"的 2.速度更快,Eclipse的启动速度 ...
- selenium 速查手册 python版
1.安装与配置 pip install selenium 基本使用selenium都是为了动态加载网页内容用于爬虫,所以一般也会用到phantomjs mac下如果要配置phantomjs环境的话 e ...
- 【翻译习作】 Windows Workflow Foundation程序开发-第一章04
1.2.3 Windows Workflow运行时 从Windows Workflow的角度看,可以将工作流活动当成是交给一个工作流处理器去执行的一系列指令或操作码.在Windows Workflo ...
- 【PL/SQL练习】自定义异常
由用户自己定义1.定义异常名称,类型exception2.举出异常(raise excepttion)3.捕获异常 SQL> declare e_user_err exception; v_de ...
- 统计Crash工具—Crashlytics
官网:https://www.crashlytics.com/login 步骤: 注意:有时候再次运行,或者换了Crashlytics账号之后,获取不到Crash信息,其实你需要把plist文件里的K ...
- MySQL:MySQL和SQL Server的区别
导读:接下来的网上商城的项目,需要用到MySQL数据库了.这个对于我来说,是一个新接触的东西,按照惯例,在刚开始学习一个东西的时候,先从宏观上去了解它.本篇博客,先介绍SQL Server的基本内容, ...
- 详解H264视频格式-2016.01.28
专业名词解释 VCL(Video Coding Layer)视频编码层 NAL(Network Abstraction Layer)网络提取层 SPS(Sequence Parameter Set) ...