字符串匹配---暴力匹配算法

假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢?

首先,先理清楚了暴力匹配算法的流程及内在的逻辑:

如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置,则有:

  • 如果当前字符匹配成功(即S[i] == P[j]),则i++,j++,继续匹配下一个字符;
  • 如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0。相当于每次匹配失败时,i 回溯,j 被置为0

举个例子,如果给定文本串S:“BBC ABCDAB ABCDABCDABDE”,和模式串P:“ABCDABD”,现在要拿模式串P去跟文本串S匹配,整个过程如下所示:

1. S[0]为B,P[0]为A,不匹配,执行第②条指令:“如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0”,然后该判断S[1]跟P[0]是否匹配,相当于模式串要往右移动一位(i=1,j=0)

2. S[1]跟P[0]还是不匹配,继续执行第②条指令:“如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0”,然后该判断S[2]跟P[0]是否匹配(i=2,j=0),从而模式串不断的向右移动一位(不断的执行“令i = i - (j - 1),j = 0”,i从2变到4,j一直为0)

3. 直到S[4]跟P[0]匹配成功(i=4,j=0),此时按照上面的暴力匹配算法的思路,转而执行第①条指令:“如果当前字符匹配成功(即S[i] == P[j]),则i++,j++”,可得S[i]为S[5],P[j]为P[1],即接下来判断S[5]跟P[1]是否匹配(i=5,j=1)

4. S[5]跟P[1]匹配成功,继续执行第①条指令:“如果当前字符匹配成功(即S[i] == P[j]),则i++,j++”,得到S[6]跟P[2]匹配也成功(i=6,j=2),如此进行下去

5. 直到S[10]为空格字符,P[6]为字符D(i=10,j=6),因为不匹配,重新执行第②条指令:“如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0”,此时,i=5,j=0,相当于判断S[5]跟P[0]是否匹配

6. 至此,我们可以看到,如果按照暴力匹配算法的思路,尽管之前文本串和模式串已经分别匹配到了S[9]、P[5],但因为S[10]跟P[6]不匹配,所以文本串就得回溯到S[5],模式串回溯到P[0],从而让文本串又接着开始从S[5]跟模式串的P[0]去匹配。接下来的匹配过程无非就是类似的逻辑思路,直到找到匹配的字符串或文本串遍历结束退出。

Java代码实现暴力匹配字符串

/**
     * 暴力匹配字符串算法
     * 思路:
     * ①如果当前字符匹配成功(即S[i] == P[j]),则i++,j++
     * ②如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0 .相当于每次匹配失败时,i 回溯,j 被置为0。
     * 时间复杂度为O(mn)(m、n分别为文本串和模式串的长度)。无需扩展存储空间。
     * @param text 文本串
     * @param pattern 模式串
     * @return  pattern返回在text中的位置
     */
    public static int bruteForceSearchPatternInText(String text,String pattern){
        int sLen = text.length();
        int pLen = pattern.length();

        char[] s = text.toCharArray();
        char[] p = pattern.toCharArray();

        while(sLen < pLen){
            return -1;
        }

        int i = 0 ;
        int j = 0 ;
        while(i < sLen && j < pLen){
            if(s[i] == p[j]){
                //如果当前字符匹配成功(即S[i] == P[j]),则i++,j++
                i = i+1;
                j = j+1;
            }else{
                //如果失配(即S[i]! = P[j]),令i = i - (j - 1),j = 0
                i = i - (j-1);
                j = 0;
            }
        }
        //匹配成功,返回模式串p在文本串s中的位置,否则返回-1
        if(j == pLen){
            return i-j;
        }else{
            return -1;
        }

    }
    

结束语:上面的算法分析过程中,第6步后,我们会发现S[5]肯定跟P[0]失配。为什么呢?因为在之前第4步匹配中,我们已经得知S[5] = P[1] = B,而P[0] = A,即P[1] != P[0],故S[5]必定不等于P[0],所以回溯过去必然会导致失配。那有没有一种算法,让i 不往回退,只需要移动j 即可呢?答案是肯定的。这种算法就是KMP算法,它利用之前已经部分匹配这个有效信息,保持i 不回溯,通过修改j 的位置,让模式串尽量地移动到有效的位置。

整理自:http://blog.csdn.net/v_july_v/article/details/7041827

时间: 2024-10-09 08:15:46

字符串匹配---暴力匹配算法的相关文章

字符串匹配暴力算法 与 字符串匹配的KMP算法

声明:先看一下阮一峰的网络日志关于字符串的KMP算法的讲解.本文图片均引用于这篇日志. 在先前的笔试中遇到了关于字符串匹配的问题,一时脑袋卡壳没写好算法.现在就来分析分析 暴力算法和KMP算法各自原理,以及代码实现,之间差异,并且总结一下好算法的一般思路. =========================================================================== 各自原理: 暴力算法: 1. 我们把长的字符串做为一个文本字符串,命名为strText,把

字符串匹配之---BF算法(暴力破解法)

写完第一篇字符串匹配文章.发现居然没有介绍啥是字符串匹配算法.啥是KMP,直接就开讲KMP的next数组有点唐突.而在我打算写第二篇的时候发现,我们为什么要有KMP算法,它究竟比普通的算法好在哪里?回过头来想想应该把普通的暴力法也写写,这样才干明确它们的好.同一时候.不要以为它是暴力法就觉得它不好,你不是必需掌握它.同学.你知道吗?差点儿全部标准库中类似字符串匹配的函数(如: java-indexof)都是採用的我们今天要将的BF(Brute Force)方法,原因见noredirect=1#c

POJ3080——Blue Jeans(暴力+字符串匹配)

Blue Jeans DescriptionThe Genographic Project is a research partnership between IBM and The National Geographic Society that is analyzing DNA from hundreds of thousands of contributors to map how the Earth was populated. As an IBM researcher, you hav

字符串匹配的三种算法

下面将介绍三种有关字符串匹配的算法,一种是朴素的匹配算法,时间复杂度为O(mn),也就是暴力求解.这种方法比较简单,容易实现.一种是KMP算法,时间复杂度为O(m+n),该算法的主要任务是求模式串的next数组.另外还有一种对KMP算法的改进,主要是求nextval数组. 第一种朴素的匹配算法: int index(char str[], char subStr[]) { int i = 0, j = 0,index = 0; while (str[i] != '\0' && subStr

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

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

[算法系列之十四]字符串匹配之Morris-Pratt字符串搜索算法

前言 我们前面已经看到,蛮力字符串匹配算法和Rabin-Karp字符串匹配算法均非有效算法.不过,为了改进某种算法,首先需要详细理解其基本原理.我们已经知道,暴力字符串匹配的速度缓慢,并已尝试使用Rabin-Karp中的一个散列函数对其进行改进.问题是,Rabin-Karp的复杂度与强力字符串匹配相同,均为O(mn). 我们显然需要采用一种不同方法,但为了提出这种不同方法,先来看看暴力字符串匹配有什么不妥之处.事实上,再深入地研究一下它的基本原理,就能找到问题的答案了. 在暴力匹配算法中,需要检

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

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

字符串匹配KMP算法的理解(详细)

1. 引言 本KMP原文最初写于2年多前的2011年12月,因当时初次接触KMP,思路混乱导致写也写得混乱.所以一直想找机会重新写下KMP,但苦于一直以来对KMP的理解始终不够,故才迟迟没有修改本文. 然近期因开了个算法班,班上专门讲解数据结构.面试.算法,才再次仔细回顾了这个KMP,在综合了一些网友的理解.以及算法班的两位讲师朋友曹博.邹博的理解之后,写了9张PPT,发在微博上.随后,一不做二不休,索性将PPT上的内容整理到了本文之中(后来文章越写越完整,所含内容早已不再是九张PPT 那样简单

字符串匹配与KMP算法笔记

>>字符串匹配问题 字符串匹配问题即在匹配串中寻找模式串是否出现, 首先想到的是使用暴力破解,也就是Brute Force(BF或蛮力搜索) 算法,将匹配串和模式串左对齐,然后从左向右一个一个进行比较, 如果不成功则模式串向右移动一个单位,直到匹配成功或者到达匹配串最后仍然不成功,返回失败. 很明显,这种算法有很多的地方可以优化,假设要搜索的串为S,长度为n,要匹配的串为M,长度为m,时间复杂度为O(nm). >>KMP算法 Knuth-Morris-Pratt算法以三个发明者命名