前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >子字符串查找----Boyer-Moore算法(从右向左匹配)

子字符串查找----Boyer-Moore算法(从右向左匹配)

作者头像
SuperHeroes
发布2018-05-30 17:58:34
1.1K0
发布2018-05-30 17:58:34
举报
文章被收录于专栏:云霄雨霁云霄雨霁

Boyer-Moore算法是一种从右向左扫描模式字符串并将它与文本匹配的算法。

举例说明Boyer-Moore算法:

有文本FINDINAHAYSTACKNEEDLE和模式字符串NEEDLE. 因为是从右向左扫描,所以会先比较模式中最后一位E和文本中下标为5的N。不匹配,因为模式字符串中也出现了N,则右移模式字符串使得模式中最右边的N(这里是位置0的N)与文本中的相应N对齐。然后接着比较模式字符串最后的E和文本中的S(下标10),不匹配,而且模式中不含有字符S,可以将模式直接右移6位,然后继续匹配......

上述方法被称为启发式的处理不匹配字符。要实现之,需要一个数组right[]保存字母表中每个字母在模式字符串中出现的最靠右的下标(如果不存在则为-1)。这个值揭示了如果发生不匹配,应该右跳跃多远。

在right[]数组计算后,算法实现起来就非常容易了。用一个索引i在文本中从左向右移动,用索引j在模式字符串中从右向左移动。内循环检查检查正文和模式字符串在位置i是否相等,如果从M-1到0的所有j,txt.charAt(i+j)都和pat.charAt(j)相等,就是找到了匹配。否则匹配失败,失败有三种情况:

  1. 如果造成失败的字符不包含在模式字符串中,则将模式字符串向右移动j+1个位置;
  2. 如果造成失败的字符包含在模式字符串中,根据right[]数组右移模式字符串;
  3. 如果这种方法无法增大i,就直接将i+1保证模式字符串至少向右移动一个位置。

在一般情况下,对于长度为N的文本和长度为M的模式字符串,该方法通过启发式处理不匹配的字符需要~N/M次比较。

代码语言:javascript
复制
public class BoyerMoore {
    private final int R; 
    private int[] right;   
    private String pat;     

    public BoyerMoore(String pat) {
        this.R = 256;
        this.pat = pat;

        right = new int[R];
        for (int c = 0; c < R; c++)
            right[c] = -1;
        for (int j = 0; j < pat.length(); j++)
            right[pat.charAt(j)] = j;
    }
    
    public int search(String txt) {
        int m = pat.length();
        int n = txt.length();
        int skip;
        for (int i = 0; i <= n - m; i += skip) {
            skip = 0;
            for (int j = m-1; j >= 0; j--) {
                if (pat.charAt(j) != txt.charAt(i+j)) {
                    skip = Math.max(1, j - right[txt.charAt(i+j)]);
                    break;
                }
            }
            if (skip == 0) return i;
        }
        return n;              
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.01.26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档