BM算法,全称是Boyer-Moore算法,1977年,德克萨斯大学的Robert S. Boyer教授和J Strother Moore教授发明了一种新的字符串匹配算法。

BM算法定义了两个规则:

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

关于坏字符规则和好后缀规则的具体讲解,以及怎么移动,可以查看阮一峰老师的详细讲解:http://www.ruanyifeng.com/blog/2013/05/boyer-moore_string_search_algorithm.html

具体代码如下:

  1     private static final int SIZE = 256; // 全局变量或者是局部变量
  2
  3     /**
  4      * 坏字符规则哈希表构建方法
  5      *
  6      * @param b
  7      *            模式串
  8      * @param m
  9      *            模式串的长度
 10      * @param bc
 11      *            散列表
 12      */
 13     private void generateBC(char[] b, int m, int[] bc) {
 14         for (int i = 0; i < SIZE; ++i) {
 15             bc[i] = -1; // 初始化bc
 16         }
 17
 18         for (int i = 0; i < m; ++i) {
 19             int ascii = (int) b[i]; // 计算b[i]的ASCII值
 20             bc[ascii] = i;
 21         }
 22     }
 23
 24     /**
 25      * 好后缀规则构建哈希表
 26      *
 27      * @param b
 28      *            模式串
 29      * @param m
 30      *            模式串长度
 31      * @param suffix
 32      *            suffix数组的下标 k,表示后缀子串的长度,
 33      *            下标对应的数组值存储的是,在模式串中跟好后缀{u}相匹配的子串{u*}的起始下标值
 34      * @param prefix
 35      *            记录模式串的后缀子串是否能匹配模式串的前缀子串
 36      */
 37     private void generateGS(char[] b, int m, int[] suffix, boolean[] prefix) {
 38         for (int i = 0; i < m; ++i) { // 初始化
 39             suffix[i] = -1;
 40             prefix[i] = false;
 41         }
 42
 43         for (int i = 0; i < m - 1; ++i) {
 44             int j = i;
 45             int k = 0; // 公共后缀子串长度
 46             while (j >= 0 && b[j] == b[m - 1 - k]) { // 与b[0, m-1]求公共后缀子串
 47                 --j;
 48                 ++k;
 49                 suffix[k] = j + 1; // j+1表示公共后缀在b[0,i]中的起始下标
 50             }
 51             if (j == -1) {
 52                 prefix[k] = true; // 如果公共后缀子串也是模式串的后缀子串
 53             }
 54         }
 55     }
 56
 57     /**
 58      * 完整的BM算法 好后缀+坏字符
 59      *
 60      * @param a
 61      *            主串
 62      * @param n
 63      *            主串的长度
 64      * @param b
 65      *            模式串
 66      * @param m
 67      *            模式串的长度
 68      * @return
 69      */
 70     public int bm(char[] a, int n, char[] b, int m) {
 71         int[] bc = new int[SIZE];
 72         generateBC(b, m, bc); // 构建坏字符哈希表
 73         int[] suffix = new int[m];
 74         boolean[] prefix = new boolean[m];
 75         generateGS(b, m, suffix, prefix); // 构建好字符哈希表
 76         int i = 0; // j 表示主串与模式串匹配的第一个字符
 77         while (i < n - m) {
 78             int j = 0;
 79             for (j = m - 1; j >= 0; --j) {// 模式串从后向前匹配
 80                 if (a[i + j] != b[j]) {
 81                     break; // 坏字符串
 82                 }
 83             }
 84             if (j < 0) {
 85                 return i;// 匹配成功,返回主串和模式串第一个匹配字符的位置
 86             }
 87             int x = j - bc[(int) a[i + j]];
 88             int y = 0;
 89             if (j < m - 1) { // 如果有好后缀的话
 90                 y = moveByGS(j, m, suffix, prefix);
 91             }
 92             i = i + Math.max(x, y);
 93         }
 94         return -1;
 95     }
 96
 97     private int moveByGS(int j, int m, int[] suffix, boolean[] prefix) {
 98         int k = m - 1 - j; // 好后缀的长度
 99         if (suffix[k] != -1) {
100             return j - suffix[k] + 1;
101         }
102         for (int r = j + 2; r <= m - 1; ++r) {
103             if (prefix[m - r] == true) {
104                 return r;
105             }
106         }
107         return m;
108     }    

转载于:https://www.cnblogs.com/ssh-html/p/10118496.html

字符串匹配算法之BM算法相关推荐

  1. diff算法阮一峰_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法

    前言 文章的一开头,还是要强调下字符串匹配的思路 将模式串和主串进行比较 从前往后比较 从后往前比较 2. 匹配时,比较主串和模式串的下一个位置 3. 失配时, 在模式串中寻找一个合适的位置 如果找到 ...

  2. 大量的数据做字符串匹配_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法...

    前言 文章的一开头,还是要强调下字符串匹配的思路 将模式串和主串进行比较 从前往后比较 从后往前比较 2. 匹配时,比较主串和模式串的下一个位置 3. 失配时, 在模式串中寻找一个合适的位置 如果找到 ...

  3. 一看就懂的字符串匹配算法 之 BM算法

    先来一个导读,关于BM算法开始有了难度,大家一定要静下心,咬着呀也得给我读下去,这样你才能有收获. 我们在文本编辑器中,我们经常用到查找及替换功能.比如说,在Word文件中,通过查找及替换功能,可以把 ...

  4. 字符串匹配算法:Horspool算法

    Horspool 字符串匹配算法对Boyer-Moore算法的简化算法. Horspool 算法是一种基于后缀匹配的方法,是一种"跳跃式"匹配算法,具有sub-linear亚线性时 ...

  5. 字符串匹配算法之Sunday算法

    字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...

  6. 字符串匹配算法:Sunday算法

    背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...

  7. 字符串处理 —— 单模式匹配 —— 朴素的字符串匹配算法(BF 算法)

    [算法流程] 朴素的字符串匹配算法即暴力匹配算法(BF,Brute Force),其本质是暴力枚举,主要特点有: 没有预处理阶段: 滑动窗口总是后移 1 位: 对模式中的字符的比较顺序不限定,可以从前 ...

  8. 双目立体视觉匹配算法-----SAD匹配算法、BM算法、SGBM算法、GC算法

    一. SAD算法 1.算法原理         SAD(Sum of absolute differences)是一种图像匹配算法.基本思想:差的绝对值之和.此算法常用于图像块匹配,将每个像素对应数值 ...

  9. 字符串匹配算法(BF算法KMP算法)

    字符串匹配算法 暴力匹配(BF)算法 KMP算法 next数组 求next数组的练习 next数组的优化(nextval数组) 练习 暴力匹配(BF)算法 BF算法,即暴力(Brute Force)算 ...

最新文章

  1. 2个YUV视频拼接技术
  2. jdbcTemplate 调用存储过程。 入参 array 返回 cursor
  3. 第三次作业——(涂江凤、邓洪虹)
  4. Java Servlet 技术简介
  5. J.U.C系列(一)CountDownLatch的使用
  6. mysql死锁分析_MySQL死锁分析
  7. 花了一个月时间梳理了一下公司的微服务核心架构,原来也不是太难...
  8. 从零使用Maven搭建ssm多模块
  9. 方法类型,模块与Stream流
  10. 《Python算法教程》——2.4 请提防黑盒子
  11. SIM900A高效完整的STM32代码
  12. Geek Challenge
  13. 项目开发中遇到接收串口数据时序混乱的问题
  14. 迅捷路由虚拟服务器设置,迅捷 FWR310 无线路由器端口映射设置指南
  15. 【计网】(一) 集线器、网桥、交换机、路由器等概念
  16. 新媒体视频导演 - 导演学前班
  17. C++八股文分享---进程
  18. 这篇文章几乎回答了你对量化对冲的所有疑问
  19. uni-app小程序到微信发布踩的坑
  20. mysql函数编写格式_MySQL函数基础——字符串函数详解

热门文章

  1. 尚硅谷-SpringMVC篇
  2. css 网站大背景(按比例缩放背景图片)
  3. 超硬核!华为智慧屏上的家庭相册竟可以自动精准分类?
  4. 多语言适配分享会演讲稿
  5. FBX SDK 总结之中文问题
  6. html默认样式重置,我们真的需要CSS重置来清除默认样式吗?
  7. elementUI时间日期组件设置的默认时间在ie中无法重置
  8. 【Spring源码】ClassPathResource 资源文件源码分析
  9. 如何预防服务器IP被封
  10. 傅里叶变换和逆变换公式的我理解意义