字符串匹配

阅读数:131 评论数:0

跳转到新版页面

分类

算法/数据结构

正文

字符串的匹配包括蛮力匹配算法,KMP算法,BM算法,Horspool算法,Sunday算法,fastsearch算法,KR算法等等。

本文主要介绍KMP算法和BM算法,它们分别是前缀匹配和后缀匹配的经典算法。所谓前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从左到右;所谓后缀匹配是指:模式串和母串的的比较从右到左,模式串的移动从左到右。看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同。

1、KMP

KMP算法中的KMP分别是指三个人名:Knuth、Morris、Pratt,与蛮力匹配算法的区别在于它会动态调整每次模式串的移动距离,而不仅仅是加一,从而加快匹配过程。

设T为母串,P为模式串,模式串的长度为m,则kmp算法的伪代码:

j:=0;
for i:=1 to n 
    while(j>0&&p[j+1]!=T[i]) j:= jump[j];
    if(p[j+1]==T[i])  j:=j+1;
    if(j==m) cout<<"pattern occurs with shift "<<i-m<<endl;

KMP算法中jump数组的构建可以通过归纳法来解决:

(1)首先确定jump[1]=0;

(2)假设jump[j]=k,也就是P[0, j] == P[k-j, k]

(3)如果P[j+1] == P[k+1],那么jump[j+1] = k+1;

(4)如果P[j+1] != P[k+1],那就接着比较P[j+1] ?= P[k1+1],其中(jump[k] = k1)

(5)如果此时P[j+1] == P[k1+1],则得出:jump[j+1] = K1 +1 = jump[k] +1。

(6)如果P[j+1] != P[K1+1],继续递归比较P[j+1] 和P[jump[jump[k]]+1]  ….  P[1];
(7)如果依次比较都不相等,那么jump[j+1] = 0;

jump[1]  = 0;
j = 0;
for (i=2;i<=m;++i)
    while(j>0&&p[j+1]!=p[i]) j=jump[j];
    if(p[j+1] = p[i]) j = j+1;
    jump[i] = j;

KMP算法最差的时间复杂度是O(n);最好的时间复杂度是O(n/m)。

其实jump数组的含义就是一个固定字符串的最长前缀和最长后缀相同的长度。例如:

ababaca

jump[1] = 0,

jump[2] = 0,对就串ab的的前缀与后缀的最长相同长度为0

jump[3] = 1, 对应中aba前缀与后缀的最长相同长度为1,相同部分为a

jump[4] = 2, abab=>ab

jump[5] = 3, ababa=>aba

jump[6] = 0, ababac

jump[[7] = 1, ababaca=>a

 

 




相关推荐

一、介绍 1、二分图 其最大的特点在于,可以将图里的顶点分为两个集合,且集合内的点没有直接关联。 2、增广路径 增广路径是指,由一个未匹配的顶点开始,经过若干个匹配顶点,最后到达对面集合的一个未匹配

0、这里假设有人要从A点去往B点。 1、找到与起始点相邻的所有可到达方块,<span style="col

MD5,即“Message-Digest Algorithm 5”(信息-摘要算法),从名字来看就知道它是从MD3、MD4发展而来的一种加密算法,其主要通过采集文件的信息摘要,从此进行计算并加密。 M

概念 Base54算法使用了单表置换算法的思想,Base64使用一个由64个字符组成的映射表。 实现原理 1、将给定的字符串转换成对应的字符编码

deflate是同时使用lz77算法与huffman编码的一个无损压缩算法。人们普遍认为deflate不受任何专利所制约,deflate压缩与解压缩的源代码可以在开源的zlib库中找到。

一、密码学的常见概念 1、代替密码 代替密码是指先建立一个替换表,加密时通过查表,将明文的每个字母依次替换为对应的字符,生成密文。 按替换表的个数又细分为: (1)单表代替密码 即一个明文字符对应一个

零-概述 ECB模式和CBC模式是最常用的两种模式。 1、需要块对齐的模式:ECB、CBC、PCBC 2、需要初始向量的模式:除了ECB模式外,都需要初始向量。 一、ECB,电子密码本 Electro

一、概述 1、图的表示法 图G = (V, E)的表示有邻接表和邻接矩阵两种形式。通常,对于| E |远小于| V | ^ 2的稀疏图,用邻接表比较合适。若图稠密或很小,或必须很快判别给定的两个顶点是

用伪代码来表示, 二分查找算法大致是这个样子的: left = 0, right = n -1 while (lef

单模式VS多模式 (1)单模式 单模就是给你一个单词,然后给你一个字符串,问你这个单词是否在这个字符串中出现过(匹配) (2)多模式 给你