字符串的模式匹配——Brute-Force算法和KMP算法

  子串的定位操作是要在主串S中找出一个与子串T相同的子串,通常把主串S称为目标,把子串T称为模式
把从目标S中查找模式为T的子串的过程称为“模式匹配”。

1.Brute-Force算法的设计思想
  Brute-Force是普通的模式匹配算法。将主串S的第1个字符和模式T的第1个字符比较,若相等,继续逐个比较后续字符;若不等,从主串的下一字符起,重新与模式的第一个字符比较,直到主串的一个连续子串字符序列与模式相等 ,返回值为S中与T匹配的子序列第一个字符的序号,即匹配成功;否则,匹配失败,返回值 0。

def index(text,tgt_str):
    j=0
    tgt_len=len(tgt_str)
    for i in range(len(text)):
        if( text[i] == tgt_str[j] ):
            j+=1
        else:
            i=i-j+1
            j=0
        if(j==tgt_len):
            return i-tgt_len+1
    return 0

2.Brute-Force算法的特点:
  每次遇到匹配不成功的情况,指针i都要移到本次匹配的开始位置的下一位,称这样的指针移动为回溯
  指针的回溯越多,简单模式匹配的执行次数越多

Brute-Force匹配算法的最坏时间复杂度为 O(n*m)
一般情况下BF算法的时间复杂度为O(n+m)

3.KMP算法的改进
  每当一趟匹配过程中出现字符比较不等时,不需回溯指针i,而是利用已经得到的“部分匹配”的结果将模式向右“滑动”尽可能远的一段距离后,继续比较
  KMP算法的时间复杂度可以达到O(m+n)

4.KMP算法的设计思想

  假设以指针 i 和 j 分别指示主串和模式中正待比较的字符,令 i 的初值为0,j 的初值为0
  若在匹配过程中,Si=Pj,则i和j分别增1,否则i不变,而j退到next[j]的位置再比较,若相等,则指针各自增1,否则j再退到下一个next值的位置,依次类推

若令next[j]=k,则next[j]表明当模式中第j个字符与主串中相应字符失配时,在模式中需重新和主串中该字符进行比较的字符的位置
模式串的next函数定义为
    

     

#coding=utf-8
str1=‘9AA8‘
text=‘8149AA86A5482A12958509AA8‘
nextList=[0]

def get_next(tgt_str):
    i=1;j=0
    global nextList
    while(i < len(tgt_str)):
        if(j == 0 or tgt_str[i-1]==tgt_str[j-1]):
            i+=1;j+=1
            nextList.append(j)
        else:
            j=nextList[j-1]
    return nextList

def Index_KMP(text,tgt_str):
    j=0
    a=len(text)
    b=len(tgt_str)
    for i in range(a):
        while j>0 and text[i]!=tgt_str[j]:
            j=nextList[j-1]         #模式串向右移动
        if( text[i] == tgt_str[j] ):
            j+=1
        if j==b:
            print ‘success‘
            print ‘location: ‘+str(i-b+1)
            j = nextList[j-1]
    else:
        print ‘no match‘

get_next(str1)
print nextList
Index_KMP(text,str1)
时间: 2024-10-11 05:38:46

字符串的模式匹配——Brute-Force算法和KMP算法的相关文章

串的模式匹配算法(BF算法和KMP算法)

串的模式匹配算法 子串的定位操作通常称为串的 模式匹配,其中T称为 模式串. 一般的求子串位置的定位函数(Brute Force) 我写java的代码是这样的 int index(String S,String T,int pos){ char[] s_arr = S.toCharArray(); char[] t_arr = T.toCharArray(); int i,j,k;//i是主串S的指针,j是模式串的指针 if(pos < 0 || pos>S.length() || S.len

字符串匹配的BF算法和KMP算法学习

引言:关于字符串 字符串(string):是由0或多个字符组成的有限序列.一般写作`s = "123456..."`.s这里是主串,其中的一部分就是子串. 其实,对于字符串大小关系不如是否相同重要.包括密码验证.hash列等. 而字符串的存储结构有两种:顺序存储结构和链式存储结构.由于不同的字符是连在一起的,所以一般是开足够大的空间进行顺序存储,这样更符合字符串的意义. 一.BF算法实现 一种暴力的.朴素的模式匹配算法,是的,时间复杂度为O(M*N).而下面的KMP算法则是O(M+N)

串匹配模式中的BF算法和KMP算法

考研的专业课以及找工作的笔试题,对于串匹配模式都会有一定的考察,写这篇博客的目的在于进行知识的回顾与复习,方便遇见类似的题目不会纠结太多. 传统的BF算法 传统算法讲的是串与串依次一对一的比较,举例设目标串S="ababcabcacb",模式串T="abcac",利用BF算法这个过程就会表示为: 将S串理解为数组,底标从0开始,即从a开始,第一次匹配过程如下: ok,当发现T串尚未匹配结束,就开始出现了错误,S串坐标右移+1,开始从b匹配,过程如下: 出现不同,继续

BF算法和KMP算法

串的模式匹配算法即确定主串中所含子串第一次出现的位置.BF算法是古典的,采用穷举的思想,而KMP算法是模式匹配算法的改进算法. 1.BF算法设计思想:将主串的第pos个字符和模式的第1个字符比较, 若相等,继续逐个比较后续字符: 若不等,从主串的下一字符(pos+1)起, 重新与第一个 字符比较.直到主串的一个连续子串字符序列与模式相等 .返回值为S中与T匹配的子序列第一个字符的序号,即匹配成功. 否则,匹配失 败. 例子:主串s="ababcabcacbab",模式t="abcac" BF算法

字符串匹配的算法(暴力算法和KMP算法)

学习字符串匹配算法有一段时间了,不过还是有点迷糊,虽然了解算法过程,但是在编码的时候还是会有些迷糊. 先把写的程序放在这里,以后有时间再来翻着看看吧! #include<iostream> #include<string> using namespace std; int KMPfind(char* s, char* p); void GetNext(char* p, int next[]); int ViolentMatch(char* s, char* p); int main

BF算法和KMP算法(javascript版本)

var str="abcbababcbababcbababcabcbaba";//主串 var ts="bcabcbaba";//子串 function BF(s,t){//BF算法 var i=0,j=0,v=-1; while(i<s.length&&j<t.length){ if(s[i]==t[j]){//相等就移动指针 i++; j++; } else{//指针归零 i=i-j+1; j=0; } } if(j==t.lengt

时空权衡之输入增强 ----字符串匹配算法Horspool算法和Boyer-Moore算法

在算法设计的时空权衡设计技术中,对问题的部分或者全部输入做预处理,对获得的额外信息进行存储,以加速后面问题的求解的思想,我们称作输入增强. 其中字符串匹配算法Horspool算法和Boyer-Moore算法就是输入增强的例子. 首先了解一下字符串匹配的概念.我们把在一个较长的n个字符的串中,寻找一个给定的m个字符的串的问题,称为字符串匹配问题.较长的串称为text,而需要寻找的串称为pattern. 字符串匹配问题的蛮力算法很好理解:我们把pattern与text第一个字符对齐,从左往右比较pa

使用Apriori算法和FP-growth算法进行关联分析(Python版)

===================================================================== <机器学习实战>系列博客是博主阅读<机器学习实战>这本书的笔记也包含一些其他python实现的机器学习算法 算法实现均采用python github 源码同步:https://github.com/Thinkgamer/Machine-Learning-With-Python ==================================

最短路径Dijkstra算法和Floyd算法整理、

转载自:http://www.cnblogs.com/biyeymyhjob/archive/2012/07/31/2615833.html 最短路径—Dijkstra算法和Floyd算法 Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Dijkstra算法是很有代表性的最短路径算法,在很多专业课程中都作为基本内容有详细的介绍,如数据结构,图论,运筹