浅谈字符串匹配算法BF 算法及 KMP 算法Word文档格式.docx

上传人:b****5 文档编号:19497819 上传时间:2023-01-06 格式:DOCX 页数:11 大小:19.96KB
下载 相关 举报
浅谈字符串匹配算法BF 算法及 KMP 算法Word文档格式.docx_第1页
第1页 / 共11页
浅谈字符串匹配算法BF 算法及 KMP 算法Word文档格式.docx_第2页
第2页 / 共11页
浅谈字符串匹配算法BF 算法及 KMP 算法Word文档格式.docx_第3页
第3页 / 共11页
浅谈字符串匹配算法BF 算法及 KMP 算法Word文档格式.docx_第4页
第4页 / 共11页
浅谈字符串匹配算法BF 算法及 KMP 算法Word文档格式.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

浅谈字符串匹配算法BF 算法及 KMP 算法Word文档格式.docx

《浅谈字符串匹配算法BF 算法及 KMP 算法Word文档格式.docx》由会员分享,可在线阅读,更多相关《浅谈字符串匹配算法BF 算法及 KMP 算法Word文档格式.docx(11页珍藏版)》请在冰豆网上搜索。

浅谈字符串匹配算法BF 算法及 KMP 算法Word文档格式.docx

循环往复,直到到达S或者T字符串的结尾。

如果是到达S串的结尾,则表示匹配失败,如果是到达T串的结尾,则表示匹配成功。

BF算法优点:

思想简单,直接,无需对字符串S和T进行预处理。

缺点:

每次字符不匹配时,都要回溯到开始位置,时间开销大。

下面是BF算法的代码实现:

bf.c

#include<

stdio.h>

 

stdlib.h>

string.h>

 

int 

index_bf(char 

*s,char 

*t,int 

pos);

index_bf_self(char 

index);

/* 

BF算法示例 

*/ 

main() 

char 

s[]="

6he3wor"

;

//标准BF算法中,s[0]和t[0]存放的为字符串长度。

t[]="

3wor"

m=index_bf(s,t,2);

//标准BF算法 

printf("

index_bf:

%d\n"

m);

m=index_bf_self(s,t,2);

//修改版BF算法,s和t中,不必再存放字符串长度。

index_bf_self:

exit(0);

字符串S和T中,s[0],t[0]存放必须为字符串长度 

例:

7hibaby!

"

T[]="

4baby"

index_bf(s,t,1);

pos:

在S中要从下标pos处开始查找T 

(说明:

标准BF算法中,为研究方便,s[0],t[0]中存放的为各自字符串长度。

) 

*/ 

pos) 

i,j;

if(pos>

=1 

&

pos 

<

=s[0]-'

0'

i=pos;

j=1;

while(i<

j<

=t[0]-'

if(s[i]==t[j]) 

i++;

j++;

else 

i=i-j+2;

if(j>

t[0]-'

return 

i-t[0]+'

-1;

修改版,字符串s和t中,不必再包含字符串长度。

hibaby"

baby"

index_bf_self(s,t,0);

index:

在s中,从几号下标开始查找 

index) 

i=index,j=0;

while(s[i]!

='

\0'

while(*(t+j)!

*(s+i+j)!

if(*(t+j)!

=*(s+i+j)) 

break;

if(*(t+j)=='

i;

j=0;

}

测试结果:

二、KMP算法:

由BF算法例图中可知,当S[8]和T[8]不匹配时,S和T都需要回溯,时间复杂度高。

因此,出现了KMP算法。

先看下图:

从图中,我们可以很容易的发现,S不必回溯到S[1]的位置,T也不必回溯到T[0]的位置,因为前面的字符,S和T中都是相等的。

如果S不回溯的话,那T该怎么办呢?

我们也可以很容易的发现,S中5、6、7号字符和T中0、1、2号字符是相等的。

故T直接回溯到T[3]的位置即可。

此时我们就省去了很多不必要的回溯和比较。

那么这些都是我们从图中直观得出的结论,如果换做其他字符,我们又如何知道T该回溯到几号字符呢?

先看看KMP算法的思想:

假设在模式匹配的进程中,执行T[i]和W[j]的匹配检查。

若T[i]=W[j],则继续检查T[i+1]和W[j+1]是否匹配。

若T[i]W[j],则分成两种情况:

若j=1,则模式串右移一位,检查T[i+1]和W[1]是否匹配;

若1

图中,首先构造Next数组,构造过程见图解(这里讲解的简单了些,本文重点是理清KMP算法思路,故没有赘述,想细究的同学,自己谷歌一下吧)。

构造完毕后,当S[8]和T[8]失配时,我们从next数组可知,T应回溯到T[3]的位置,重新开始比较。

样子有点像下面这样:

如果S[8]和T[3]再次失配,则继续回溯,即比较S[8]和T[0]。

如果再次失配,T已无回溯元素可言,此时,S向后移动,即开始比较S[9]和T[0]……结束条件就是:

到达字符串S或者T的结尾。

若是S结尾,则返回-1.若是T结尾,则匹配成功。

返回S中T串开始时的下标即可。

下面给出个小例子,仅供大家练习使用:

下面给出KMP算法标准代码(即数组首元素保存的是字符串长度):

kmp.c

void 

get_next(char 

*next);

index_kmp(char 

main(int 

argc,char 

*argv[]) 

chart[]="

6ababcd"

intnext[7];

get_next(t,next);

inti;

for(i=0;

i<

7;

i++) 

printf("

%d,"

next[i]);

\n"

);

6helwor"

m=index_kmp(s,t,1);

利用KMP算法,求解字符串t在s中的开始位置。

在字符串S中,从下标pos开始查找是否含有t子串 

如果含有,返回t在s中的下标起始位置。

否则,返回-1. 

注意:

s和t中首元素保存的都是字符串的长度。

next[sizeof(t)];

get_next(t,next);

if(0==j 

|| 

s[i]==t[j]) 

j=next[j];

*next) 

i=0;

next[1]=0;

while(j<

if(0==i 

t[i]==t[j]) 

if(t[i]!

=t[j]) 

next[j]=i;

next[j]=next[i];

i=next[i];

修改版KMP算法:

(字符数组首元素不再保存字符串长度,更符合实际应用)kmp2.c

main(void) 

helloworld!

world"

intnext[strlen(t)];

strlen(t);

m=index_kmp(s,t,0);

在字符串s中,从下标index开始查找是否含有字符串t.如果有,返回t在s中的开始位置;

如果没有,返回-1。

(使用KMP算法实现) 

注:

字符数组s和t中,不再保存字符串长度。

next[strlen(t)];

t[j]!

continue;

//从模式匹配数组中,获取要回溯到的结点 

if(0==j) 

//单独处理第一个字符 

if(t[j]=='

//表示字符串t中,所有字符已匹配完毕 

i-strlen(t);

//因为i以匹配至s中t字符串的结尾。

因为要返回的是s中t的开始下标,故i-strlen(t). 

KMP算法之next数组代码 

next数组定义:

当模式匹配串T失配的时候,next数组对应的元素知道应该用T串的哪个元素进行下一轮的匹配。

//Prefix前缀 

//Postfix后缀 

next[0]=0;

//自定义的,0和1都从0开始匹配 

while(t[j]!

if(t[i]==t[j]) 

//若前后字符匹配,则向前推进 

//前后字符不匹配,则回溯。

注意,此时是i和j不匹配,因此,根据next数组定义,要回溯到next[i]的值。

if(0==i) 

//当回溯到首字符时,单独进行处理 

next[++j]=++i;

next[++j]=i;

示例测试结果:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 成人教育 > 自考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1