KMP

王朝百科·作者佚名  2010-01-05  
宽屏版  字体: |||超大  

KMP

KMP在一个长字符串中匹配一个短子串的无回溯算法。

朴素算法先看看最“朴素”的算法:

///find a template in a string.

#include<string.h>

#include<stdio.h>

int Index(char *S, char *T, int pos)

{

int k=pos, j=0;

while(k <strlen(S) && j<strlen(T))//未超出字符串的长度

{

if (S[k] == T[j]) { ++k; ++j;} //如果相同,则继续向后比较

else {k = k-j+2; j =1;} //如果不同,就回溯,重新查找

}

if (j>T[0]) return k-strlen(T);

else return 0;

}

KMP算法KMP算法是通过分析子串,预先计算每个位置发生不匹配的时候,所需GOTO的下一个比较位置,整理出来一个next数组,然后再上面的算法中使用。

讲解一下:

当我们分析一个子串时,例如:abcabcddes. 需要分析一下,每个字符x前面最多有多少个连续的字符和字符串从初始位置开始的字符匹配。然后+1就行了(别忘了,我们的字符串都是从索引1开始的)当然,不要相同位置自己匹配,默认第一个字符的匹配数是0。

定义如下:设字符串为 x1x2x3...xn ,其中x1,x2,x3,... xi,... xn均是字符,设ai为字符xi对应的整数。则a=m,当且仅当满足如下条件:字符串x1x2...xm equals 字符串x(i-m+1)...xi-1 xi 并且x1x2...xm x(m+1) unequals x(i-m) x(i-m+1)...xi-1 xi。

举例如下:

abcabcddes

0111234111

|----------------------默认是0

--| | |-----------------不能自己相同字符匹配,所以这里者能认为是没有所以是0+1 =1

------| | |-----------前面的字符和开始位置的字符相同,所以是2,3,4

-----------| | | |-------不匹配只能取1。

希望能明白的是,如果开始字符是 Ch1的话,那么我们就是要在串中第2个Ch1后面的位置开始自己和自己匹配,计算最大的吻合度。

程序写出来就是:

void GetNext(char* T, int *next)

{

int k=1,j=0;

next[1]=0;

while( k〈 T[0] ){

if (j ==0 || T[k] == T[j])

{

++k;

++j;

next[k] = j;

}

else j= next[j];

}

}

但是这个不是最优的,因为他没有考虑aaaaaaaaaaaaaaaaaaab的情况,这样前面会出现大量的1,这样的算法复杂度已经和最初的朴素算法没有区别了。所以稍微改动一下:

void GetNextEx(char *T, char *next)

{

int i=k,j=0; next[1] = 0;

while(k < T[0])

{

if (j == 0 || T[k] == T[j])

{

++k; ++j;

if (T[k] == T[j])

next[k] = next[j];

else

next[k] = j;

}

else j = next[j];

}

}

现在我们已经可以得到这个next字符串的值了,接下来就是KMP算法的本体了:

相当简单:

int KMP(char* S, char* T, int pos)

{

int k=pos, j=1;

while (k){

if (S[k] == T[j]){ ++k; ++j; }

else j = next[j]

}

if (j>T[0]) return k-T[0];

else return 0;

}

和朴素算法相比,只是修改一句话而已,但是算法复杂度从O(m*n) 变成了:O(m)

串的最大匹配算法摘要:给定两个串S和T,长分别m和n,本文给出了一个找出二串间最大匹配的算法。该算法可用于比较两个串S和T的相似程度,它与串的模式匹配有别。

关键词:模式匹配 串的最大匹配 算法

Algorithm on Maximal Matching of Strings

Lin YuCai Xiang YongHong Zhang ChunXia Zhang JianJun

(Computer Science Department of Yunnan Normal University Kunming 650092)

ABSTRACT Given Two Strings S of length m and T of length n,the paper presents an algorithm which finds the maximal matching of them. The algorithm can be used to compare the similarility of the two strings S and T, it is different with the strings' pattren matching.

KEY WORDS Pattern Matching Maximal Matching of Strings Algorithm

1 问题的提出

字符串的模式匹配主要用于文本处理,例如文本编辑。文本数据的存储(文本压缩)和数据检索系统。所谓字符串的模式匹配[2],就是给定两个字符串S和T,长度分别为m和n,找出T中出现的一个或多个或所有的S,在这方面已经取得了不少进展[3][4][5][6][7][8][9][10][11]。本文从文本处理的另一个角度出发,找出两个串的最大匹配,比较其相似程度[1]。它主要应用于文本比较,特别是在计算机辅助教学中。显然前者要找S的完全匹配,而后者并无此要求。例如,若S=ABCD,T=EFABCDX,那么模式匹配的结果就是找出了T中的一个ABCD,而我们算法的结果就是S能与T的ABCD完全匹配,但是T中还有3个字符是比S多出来的,也就是说在S中有100%的字符与T中的匹配,而在T中有57%的字符与S中的匹配。若S= ABCDFE,T=AFXBECDY。则在模式匹配中S与T无匹配项,但在我们的算法中就能发现T中存在A,B,C,D,但D后不存在E,F。而且S中也存在A,B,C,D,且具有顺序性。这样就能公正地评价S,T的区别。得知其相似程度。

文章的组织如下:首先介绍基本定义和问题的描述;第三节是算法设计;最后是本文总结。

2 问题的描述

设∑为任意有限集,其元称为字符,w:∑→N为∑到N的函数,称为∑的权函数(注:本文仅讨论权值恒为1的情况)。∑*为∑上的有限字符串集合,那么对任意S,T∈∑*,设S=a1a2…am,T=b1b2…bn,m>0,n>0。记<m>={1,2, …,m},<n>={1,2, …,n},则称{(i,j)∣i∈<m>,j∈<n>,ai=bj}为S与T的匹配关系集,记作M(S,T),称M为S与T的一个(容许)匹配,若对任意(i,j), ( i',j' )∈,① i< i',当且仅当j< j',② i= i'当且仅当j= j'。S与T的匹配中满足 最大者,称为S与T的最大匹配。若C(i,j)为N上的m×n矩阵,且满足:

则称矩阵C为串S与T的匹配关系阵。

于是求串S与T的最大匹配,等价于求C中的一个最大独立点集M,它满足,若ci,j,ci',j'∈M,则i< i' 当且仅当j< j',i=i'当且仅当j=j'。我们称这样的最大独立点集为C的最大C-独立点集。

例:设∑为所有字母的集合,对任意x∈∑,w(x)≡1,设S与T分别为:S=“BOOKNEWS”,T=“NEWBOOKS”。则我们可以得到S与T两个匹配:

这里=5;

这里 =4。

显然为串S与T的最大匹配。

S与T的匹配关系阵C可表示如下:

其中带圈的部分为一最大C-独立点集。

3 算法设计

我们仅就权值为一的情况进行讨论。

设S和T为任意给定串,C为的S与T匹配关系阵,那么由2的讨论知,求S与T的最大匹配问题,等价于求C的最大C-独立点集问题。因而,为了解决我们的问题,只要给出求C的最大C-独立点集的算法就可以了。

显然,为了求出C的最大C-独立点集,我们可以采用这样的方法:搜索C的所有C-独立点集,并找出它的最大者。这种方法是可行的,但并不是非常有效的。这会使问题变得很繁,复杂度很大。因此,我们先对问题进行分析。

在下面的讨论中,我们把C的任一C-独立点集={ai1,j1,…,ais,js},记作=ai1,j1…ais,js,i1 <…< is。于是可看作阵C中以1为节点的一条路,满足:对路中的任意两节点,均有某一节点位于另一节点的右下方。称这种路为右下行路。

于是求C-独立点集等价于求阵C的右下行路。这种求右下行路的搜索可以逐行往下进行。

命题1. 若 =αai,jβ和ψ=α'ai,jσ为C的两个C-独立点集,且α为α'的加细,则存在C-独立点集'=αai,jδ,满足≥。

命题2. 若 =αai,jβ和ψ=α'ai+k,jσ为C的两个C-独立点集,且≥,则存在C-独立点集'=αai,jδ,满足≥。

命题3. 若 =αai,jβ和ψ=α'ai,j+kσ为C的两个C-独立点集,且≥,则存在C-独立点集'=αai,jδ,满足≥。

由命题1知,在搜索右下行路的过程中,如果已获得了某一C-独立点集的某一初始截段αai,j和另一C-独立点集ψ的某一初始截段α'ai,j,且有≤,则我们可以停止对ψ的进一步搜索。

由命题2知,在搜索右下行路的过程中,在某一列j存在某两个C-独立点集的某初始截段=ai1,j1…ais,j和ψ=al1,m1…alt,j,如果≥,但lt>is,则我们可以停止对ψ的进一步搜索。

由命题3知,在搜索右下行路的过程中,在某一行i存在某两个C-独立点集的某初始截段=ai1,j1…ai,js和ψ=ai1,m1…ai,mt,如果≥,但mt>js,则我们可以停止对ψ的进一步搜索。

由此可见,并不要求搜索所有C的最大C-独立点集,而可以采用比这简单得多的方法进行计算。那么按照我们上面的三个命题,来看如下实例:

首先我们得到=B(在上的节点用①表示),我们向右下方找路,可以发现,在第4列有两个1,根据命题2,我们选择上面的一个1,也就是说选择第1行的那个1,而不要第2行的那个1。同时我们也发现在第1行也有两个1,由命题3知,我们选择左边的那个1,即第4列的那个1。此时=BO。但是当我们的算法运行到第4行时,=BOOK,由于K在第3行第6列,而本行的1在第1列,在路最后一个节点K的左边,那么我们必须新建一条路ψ,因为我们并不能确定是否以后就有≥,当算法运行到第6行时,=BOOK,ψ=NEW,=4,=3,我们将S链到路上,此时我们得到最长右下行路=BOOKS,=5。这样我们就可以计算出这两个字符串的匹配程度。

在我们的算法设计过程中,用到了两个技巧。技巧之一,矩阵C不用存储,是动态建立的,节省了空间。技巧之二,本算法并不要求所有的S与T中所有的元素都相互进行比较,也并不存储所有的右下行路,节省了时间和空间。由矩阵中1的出现情况可见,本算法所需的空间和时间都远小于O(mn)

4 结束语

本文给出了一个与模式匹配不同的,具有若干应用的,串的最大匹配算法,该算法已经在机器上实现,达到了预期的效果。本文仅讨论权值恒为1的情况,对于权值任意的情形不难由此得到推广。

C语言代码(C Code)#include<stdio.h>

#include<string.h>

void getnext(int next[],char s[],int l)

{

int i=1,j=0;

next[1]=0;

while(i<l)

{

if(j==0 || s[i]==s[j])

{

i++;j++;

next[i]=j;

}

else

j=next[j];

}

}

int KMP(char s1[],char s2[],int l1,int l2,int next[])

{

int i,j;

i=j=1;

while(i<=l1 && j<=l2)

{

if(j==0||s1[i]==s2[j])

{

i++;j++;

}

else

j=next[j];

}

if(j>l2)

return(i-l2);

return 0;

}

int main()

{

int next[10001],ans;

char s1[10001],s2[10001],l1,l2;

scanf("%s",s1+1);

scanf("%s",s2+1);

l1=strlen(s1+1);

l2=strlen(s2+1);

getnext(next,s2,l2);

ans=KMP(s1,s2,l1,l2,next);

if(ans!=0)

printf("%d

",ans);

else

printf("No!

");

system("pause");

return 0;

}

KMP播放器K-multimedia player的缩写

来自韩国的影音全能播放器,与Mplayer一样从linux平台移植而来的Kmplayer(简称KMP)几乎可以播放您系统上所有的影音文件。通过各种插件扩展KMP可以支持层出不穷的新格式。强大的插件功能,直接从Winamp继承的插件功能,能够直接使用winamp的音频 ,输入,视觉效果插件,而通过独有的扩展能力,只要你喜欢,可以选择使用不同解码器对各种格式进行解码。

KMPlayer The Professional Media Player!

它支持 Winamp 2/5 的输入、常规、DSP、视觉效果、媒体库插件。无须注册表支持直接调用 Directshow 滤镜!FFdshow 的视觉特效系统~超强的 GUI 界面~安装电视卡后可以直接代替原软件直接收看电视~支持播放 DVD/VCD 以及绝大多数电脑的媒体文件(AVI 支持 Xvid/DivX/3vid/H264 OGG/OGM/MKV 容器/AC3/DTS 解码~Monkey Audio 解码~)强烈推荐!此播放器除了会将自己的配置信息写入注册表外绝对绿色~

KMplayer内置目前常见的所有解码器,包括real,QT等。

另外KMplayer安装版也是目前很少见的检查流氓软件的安装方式,如果一旦有恶意的汉化小组汉化并捆绑了流氓软件。该安装程序自动会识别,并作出提示,建议用户不要安装,虽然不是特别准确,但KMplayer的无广告及第三方插件的特点使其深受好评。

目前韩国官方已经在Kmplayer里自带了中文字库,只要用户是中文系统,软件就会自动识别,十分方便。

KMP版本:

KMPlayer2.9.3.1434

kmp官方中文论坛

http://www.kmplayer.com/forums/forumdisplay.php?f=7

 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝百科 版权所有