Boyer-Moore(BM)算法,文本查找,字符串匹配问题

KMP算法的时间复杂度是O(m + n),而Boyer-Moore算法的时间复杂度是O(n/m)。文本查找中“ctrl + f”一般就是采用的BM算法。

Boyer-Moore算法的关键点:

从右遍历,如果有txt里面的i+j元素和pat里面的j元素不一致,调整。根据right[]调整,right[]类似与KMP算法里面的nextval。skip = j - right[txt.charat(i+j)]; if(skip < 1) skip = 1;  i+=skip; 即找txt里面的第i+j个元素在pat里面的最右边的位置是哪儿,如果存在,两个对齐。如果不存在,直接将i后移到i+j+1的位置。代码如下:

class Solution {
public:
    bool search(string pat, string txt) {
        //字符串匹配问题,使用BM算法

        //计算跳跃表
        //-----------------------------------------------
        //2^8,一个字符只占一个字节,共8位
        int* right = new int[SIZE]; 

        //初始化所有值为-1
        for(int i = 0; i < SIZE; i++){
            right[i] = -1;
        }

        //包含在pat模式串中的值为它在其中出现的最右值
        for(int i = 0; i < pat.size(); i++){
            right[pat[i]] = i;
        }
        //-----------------------------------------------
        //在txt中查找字符串pat
        int N = txt.size();
        int M = pat.size();
        int skip = 0;
        for(int i = 0; i <= N - M; i += skip){
            //模式串和文本在位置i匹配么?
            //匹配失败时,通过跳跃将文本中的字符和它在模式字符串
            //出现的最右位置对齐
            skip = 0;
            for(int j = M - 1; j >= 0; j--){
                if(txt[i + j] != pat[j]){
                    skip = j - right[txt[i + j]];
                    if(skip < 1)    skip = 1;
                    break;
                }
            }
            if(skip == 0)    {
                delete[] right;
                return true;    //或者return i; 找到匹配
            }
        }

        delete[] right;
        return false;   //未找到匹配
    }
private:
    const int SIZE = 256;
};
时间: 2024-11-05 23:30:42

Boyer-Moore(BM)算法,文本查找,字符串匹配问题的相关文章

算法题之字符串匹配问题

我最近复习一道困难程度的算法题,发现了许多有趣之处.在借鉴了他人解法后,发现从最简单的情况反推到原题是一种解锁新进阶的感觉.从递归到动态规划,思维上一步一步递进,如同一部跌宕起伏的小说,记录下来和诸君共赏之. 题目如下: 给你一个字符串?s?和一个字符规律?p,请你来实现一个支持 '.'?和?'*'?的正则表达式匹配. '.' 匹配任意单个字符 '*' 匹配零个或多个前面的那一个元素 所谓匹配,是要涵盖?整个?字符串?s的,而不是部分字符串. 说明: s?可能为空,且只包含从?a-z?的小写字母

数据结构与算法之美-字符串匹配(上)

BF (Brute Force) 暴力/朴素匹配算法 主串和模式串 我们在字符串 A 中查找字符串 B,那字符串 A 就是主串,字符串 B 就是模式串. 我们把主串的长度记作 n,模式串的长度记作 m.因为我们是在主串中查找模式串,所以 n>m. BF算法思想 在主串中,检查起始位置分别是 0.1.2-n-m 且长度为 m 的 n-m+1 个子串,看有没有跟模式串匹配的. BF算法的缺点 在极端情况下,如主串是"aaaaa-aaaaaa",模式串是"aaaaab&quo

算法笔记_009:字符串匹配【蛮力法】

1 问题描述 给定一个n个字符组成的串(称为文本),一个m(m <= n)的串(称为模式),从文本中寻找匹配模式的子串. 2 解决方案 2.1 具体编码 package com.liuzhen.chapterThree; public class BruteForceStringMatch { //根据文本串N,和模式串M,返回第一个匹配模式串的子串在N中的位置 public static int getStringMatch(int[] N , int[] M){ int n = N.leng

算法模板——KMP字符串匹配

功能:输入一个原串,再输入N个待匹配串,在待匹配串中找出全部原串的起始位置 原理:KMP算法,其实这个东西已经包含了AC自动机的思想(fail指针/数组),只不过适用于单模板匹配,不过值得一提的是在单模板大量匹配待匹配串时,这个会有相当大的优势,AC自动机虽然好想一些,但是在这一类问题上的性价比就略低了 1 var 2 i,j,k,l,m,n:longint; 3 a:array[0..100000] of longint; 4 s1,s2:ansistring; 5 begin 6 readl

字符串匹配(BF,BM,Sunday,KMP算法解析)

字符串匹配一直是计算机领域热门的研究问题之一,多种算法层出不穷.字符串匹配算法有着很强的实用价值,应用于信息搜索,拼写检查,生物信息学等多个领域. 今天介绍几种比较有名的算法: 1. BF 2. BM 3. Sunday 4. KMP -,BF算法 BF(Brute Force)算法又称为暴力匹配算法,是普通模式匹配算法. 其算法思想很简单,从主串S的第pos个字符开始,和模式串T的第一个字符进行比较,若相等,则主串和模式串都后移一个字符继续比较:若不相同,则回溯到主串S的第pos+1个字符重新

【算法】字符串匹配之Z算法

在很长一段时间,求文本与单模式串匹配,我只用KMP.后来我在CF上看到Z算法,用的人也不少.在学习之后,我感觉Z算法也是很精妙的.在以前的博文中也有过用Z算法来解决字符串匹配的题目. 下面介绍一下Z算法. 先一句话讲清楚Z算法能求什么东西. 输入为一个字符串s,Z算法可以求出这个字符串每一个后缀与自身的最长公共前缀LCP. 接下来,介绍Z算法的具体内容. 记字符串s的长度为n. Z算法需要维护一对值,记为left和right,简记为L和R.L和R满足s[L,R]为s串的前缀.当i为1的时候,暴力

BM算法详解(转)

1977 年,Robert S.Boyer和J Strother Moore提出了另一种在O(n)时间复杂度内,完成字符串匹配的算法,其在绝大多数场合的性能表现,比KMP算法还要出色,下面我们就来详细了解一下这 一出色的单模式匹配算法,在此之前推荐读者读一下我的另一篇文章<KMP算法详解>,对于透彻理解BM算法大有裨益. 在讲解Boyer-Moore算法之前,我们还是要提一提KMP算法的老例子,当模式串与目标串匹配至如下位置时:  1  2  3  4  5  6  7  8  9 10 11

字符串匹配常见算法(BF,RK,KMP,BM,Sunday)

今日了解了一下字符串匹配的各种方法. 并对sundaysearch算法实现并且单元. 字符串匹配算法,是在实际工程中经常遇到的问题,也是各大公司笔试面试的常考题目.此算法通常输入为原字符串(string)和子串(pattern),要求返回子串在原字符串中首次出现的位置.比如原字符串为"ABCDEFG",子串为"DEF",则算法返回3.常见的算法包括:BF(Brute Force,暴力检索).RK(Robin-Karp,哈希检索).KMP(教科书上最常见算法).BM(

算法——蛮力法之顺序查找和蛮力字符串匹配

接着昨天的选择排序和冒泡排序之后,今天来实现一下顺序查找和蛮力字符串匹配两个算法. 顺序查找就是将给定的查找键和列表周玲的每个元素进行比较,直到找到一个匹配成功的元素返回该元素下标,查找成功,或者查找整个列表二没有匹配元素,查找失败.这里记录一下限位器版顺序查找方法.限位器就是指将查找键添加到列表最后,这样在查找的过程中,不用再每次都判断是否到达列表尾部来判断查找是否失败,而是在查找结束后,判断匹配元素下标是否小于n(假设列表有n个元素)来判断查找是否成功.下面是限位器版顺序查找算法: 限位器版