字符串匹配算法之BM算法
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算法相关推荐
- diff算法阮一峰_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法
前言 文章的一开头,还是要强调下字符串匹配的思路 将模式串和主串进行比较 从前往后比较 从后往前比较 2. 匹配时,比较主串和模式串的下一个位置 3. 失配时, 在模式串中寻找一个合适的位置 如果找到 ...
- 大量的数据做字符串匹配_【重学数据结构与算法(JS)】字符串匹配算法(三)——BM算法...
前言 文章的一开头,还是要强调下字符串匹配的思路 将模式串和主串进行比较 从前往后比较 从后往前比较 2. 匹配时,比较主串和模式串的下一个位置 3. 失配时, 在模式串中寻找一个合适的位置 如果找到 ...
- 一看就懂的字符串匹配算法 之 BM算法
先来一个导读,关于BM算法开始有了难度,大家一定要静下心,咬着呀也得给我读下去,这样你才能有收获. 我们在文本编辑器中,我们经常用到查找及替换功能.比如说,在Word文件中,通过查找及替换功能,可以把 ...
- 字符串匹配算法:Horspool算法
Horspool 字符串匹配算法对Boyer-Moore算法的简化算法. Horspool 算法是一种基于后缀匹配的方法,是一种"跳跃式"匹配算法,具有sub-linear亚线性时 ...
- 字符串匹配算法之Sunday算法
字符串匹配查找算法中,最着名的两个是KMP算法(Knuth-Morris-Pratt)和BM算法(Boyer-Moore).两个算法在最坏情况下均具有线性的查找时间.但是在实用上,KMP算法并不比最简 ...
- 字符串匹配算法:Sunday算法
背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...
- 字符串处理 —— 单模式匹配 —— 朴素的字符串匹配算法(BF 算法)
[算法流程] 朴素的字符串匹配算法即暴力匹配算法(BF,Brute Force),其本质是暴力枚举,主要特点有: 没有预处理阶段: 滑动窗口总是后移 1 位: 对模式中的字符的比较顺序不限定,可以从前 ...
- 双目立体视觉匹配算法-----SAD匹配算法、BM算法、SGBM算法、GC算法
一. SAD算法 1.算法原理 SAD(Sum of absolute differences)是一种图像匹配算法.基本思想:差的绝对值之和.此算法常用于图像块匹配,将每个像素对应数值 ...
- 字符串匹配算法(BF算法KMP算法)
字符串匹配算法 暴力匹配(BF)算法 KMP算法 next数组 求next数组的练习 next数组的优化(nextval数组) 练习 暴力匹配(BF)算法 BF算法,即暴力(Brute Force)算 ...
最新文章
- 2个YUV视频拼接技术
- jdbcTemplate 调用存储过程。 入参 array 返回 cursor
- 第三次作业——(涂江凤、邓洪虹)
- Java Servlet 技术简介
- J.U.C系列(一)CountDownLatch的使用
- mysql死锁分析_MySQL死锁分析
- 花了一个月时间梳理了一下公司的微服务核心架构,原来也不是太难...
- 从零使用Maven搭建ssm多模块
- 方法类型,模块与Stream流
- 《Python算法教程》——2.4 请提防黑盒子
- SIM900A高效完整的STM32代码
- Geek Challenge
- 项目开发中遇到接收串口数据时序混乱的问题
- 迅捷路由虚拟服务器设置,迅捷 FWR310 无线路由器端口映射设置指南
- 【计网】(一) 集线器、网桥、交换机、路由器等概念
- 新媒体视频导演 - 导演学前班
- C++八股文分享---进程
- 这篇文章几乎回答了你对量化对冲的所有疑问
- uni-app小程序到微信发布踩的坑
- mysql函数编写格式_MySQL函数基础——字符串函数详解