编制kmp字符串匹配实验报告

编制kmp字符串匹配实验报告
编制kmp字符串匹配实验报告

实验报告

题目:编制字符串匹配的KMP算法

班级:OOO 姓名:XXX

学号:ASDFGHJK 完成日期:20XX.XX.XX

一、需求分析

1.字符串匹配试求子串位置的定位函数,普通的字符串匹配函数时间复杂度较大达到了O(m*n),而KMP算法则可以将时间复杂度简化到O(m+n)。

2.本演示程序中,字符串的元素为除换行、退格等字符外的其他字符,字符串长度<=MAXSIZE,字符串的输入的形式为string[0]储存长度,从string[1]开始存储字符,并以’\0’做结束标志,字符串中字符顺序不限,且允许出现重复字符,不能出现非法字符。输入两个字符串后,输入一个整形数pos,pos<=MAXSIZE,pos的值必须合法。输出的结果为一个整形数,表示,从第一个字符串的pos位置开始,之后的子串能否与第二个字符串匹配,若能,输出匹配首地址的编号,若不能,输出0。

3.程序执行的命令包括:

1)构造字符串1;

2)构造字符串2;

3)kmp算法;

4)得到next[];

4.测试数据

1)string1=’abababab’ string2=’aba’ pos=1 output=1;

2)string1=’abababab’ string2=’aba’ pos=6 output=0;

二、概要设计

KMP算法是D.E.Knuth与V.R.Pratt和J.H.Morris同时发现的一种模式匹配的高效算法,,可以在O(m+n)的时间数量级上完成串的模式匹配操作。其改进在于:每当一趟匹配过程中出现的字符比较不等时,不需要回溯i指针,而是利用已经得到的?部分匹配?的结果将模式向右?滑动?尽可能远的一段距离后,继续进行比较。

为实现上述上述程序功能,应以串的定长顺序存储表示来存放字符串,且需要串的抽象数据类型。

1.串的定长顺序存储表示为:

#define MAXSTRLEN 255//用户可在255以内定义最大串长

typedef char SString[MAXSTRLEN+1];//0号单元存放串的长度

2.串的抽象数据类型定义为:

ADT String{

数据对象:D={ai|ai∈CharacterSet,i=1,2,...,n,n>=0}

数据关系:R1={|ai-1,ai∈D,i=1,2,...,n}

基本操作:

GetString(SString &S)

初始条件:存在串的指针。

操作结果:生成一个由键盘键入的字符串S。

strlen(SString S)

初始条件:串S存在。

操作结果:返回S的元素个数,称为串的长度。

Index(SString S,SString T,int pos)

初始条件:串S和T存在,T是非空串,1<=pos<=Strlength(S)-pos+1.

操作结果:若主串S中存在和串T值相同的子串,贼返回它在主串S中第pos 个字符之后第一次出现的位置;否则函数值为0。

}//ADT String

3.KMP算法中,用到next函数,定义:

void get_next(SString T,int next[])

4.函数的调用关系图

main()->GetString()->strlenth()

->index_KMP->get_next()

三、调试分析

1.在GetString()中开始用了gets(S),S[0]没有用来记录字符串的长度,导致在后续的程序中运算出错。

2.next函数在某些情况下存在缺陷。例如模式‘aaaaa’在和主串‘aaabaaaab’匹配时,当i=4、j=4,时不匹配,需要进行多余的三次比较,实际上,因为模式中第1、2、3、个字符和第4个字符都相等,因此不再需要和主串中第四个字符进行比较,而可以将模式一气向右滑动4个字符的位置直接进行i=5、j=1时的字符比较。这就是说,若按上述定义得到next[j]=k,而模式中pj=pk,则当主串中字符si和pj不比较不等时,不需要在和pk进行比较,而直接和pnext[k]进行比较,即此时的next[j]应该和next[k]相同。由此得到修正算法:void get_nextval(SString T,int nextval[])

四、测试结果

1.S=’abababab’ T=’aba’ pos=1 :1;

2.S=’abababab’ T=’aba’ pos=6 :0;

五、附录

源程序文件清单:

#define MAXSTRLEN 255

#include

#include

#include

int next[MAXSTRLEN+1],nextval[MAXSTRLEN+1]; typedef char SString[MAXSTRLEN+1];

int Index_KMP(SString S,SString T,int pos) {

int i,j=1;

i=pos;

while(i<=S[0]&&j<=T[0])

{

if(j==0||S[i]==T[j]){i++;j++;}

else j=next[j];

}

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

else return 0;

}

void get_next(SString T,int next[])

{

int i=1,j;

next[1]=0;

j=0;

while(i

{

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

{

++i;++j;

next[i]=j;

}

else j=next[j];

}

}

void get_nextval(SString T,int nextval[]) {

int i=1,j=0;

nextval[1]=0;

while(i

{

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

{

i++;j++;

if(T[i]!=T[j])nextval[i]=j;

else nextval[i]=nextval[j];

}

else j=nextval[j];

}

}

void GetString(SString &S)

{

gets(S+1);

S[0]=strlen(S+1);

}

int main()

{

SString S,T;

int pos;

GetString(S);

GetString(T);

get_next(T,next);

scanf("%d",&pos);

printf("%d",Index_KMP(S,T,pos));

return 0;

}

字符串的模式匹配算法

在前面的图文中,我们讲了“串”这种数据结构,其中有求“子串在主串中的位置”(字符串的模式匹配)这样的算法。解决这类问题,通常我们的方法是枚举从A串(主串)的什么位置起开始与B串(子串)匹配,然后验证是否匹配。假设A串长度为n,B串长度为m,那么这种方法的复杂度是O(m*n)的。虽然很多时候复杂度达不到m*n(验证时只看头一两个字母就发现不匹配了),但是我们有许多“最坏情况”,比如: A=“aaaaaaaaaaaaaaaaaaaaaaaaab”,B=“aaaaaaaab”。 大家可以忍受朴素模式匹配算法(前缀暴力匹配算法)的低效吗?也许可以,也许无所谓。 有三位前辈D.E.Knuth、J.H.Morris、V.R.Pratt发表一个模式匹配算法,最坏情况下是O(m+n),可以大大避免重复遍历的情况,我们把它称之为克努特-莫里斯-普拉特算法,简称KMP算法。 假如,A=“abababaababacb”,B=“ababacb”,我们来看看KMP是怎样工作的。我们用两个指针i和j分别表示,。也就是说,i是不断增加的,随着i 的增加j相应地变化,且j满足以A[i]结尾的长度为j的字符串正好匹配B串的前j个字符(j当然越大越好),现在需要检验A[i+1]和B[j+1]的关系。 例子: S=“abcdefgab” T=“abcdex” 对于要匹配的子串T来说,“abcdex”首字符“a”与后面的串“bcdex”中任意一个字符都不相等。也就是说,既然“a”不与自己后面的子串中任何一字符相等,那么对于主串S来说,前5位字符分别相等,意味着子串T的首字符“a”不可能与S串的第2到第5位的字符相等。朴素算法步骤2,3,4,5的判断都是多余,下次的起始位置就是第6个字符。 例子: S=“abcabcabc” T=“abcabx”

字符串匹配算法总结

Brute Force(BF或蛮力搜索) 算法: 这是世界上最简单的算法了。 首先将匹配串和模式串左对齐,然后从左向右一个一个进行比较,如果不成功则模式串向右移动一个单位。 速度最慢。 那么,怎么改进呢? 我们注意到Brute Force 算法是每次移动一个单位,一个一个单位移动显然太慢,是不是可以找到一些办法,让每次能够让模式串多移动一些位置呢? 当然是可以的。 我们也注意到,Brute Force 是很不intelligent 的,每次匹配不成功的时候,前面匹配成功的信息都被当作废物丢弃了,当然,就如现在的变废为宝一样,我们也同样可以将前面匹配成功的信息利用起来,极大地减少计算机的处理时间,节省成本。^_^ 注意,蛮力搜索算法虽然速度慢,但其很通用,文章最后会有一些更多的关于蛮力搜索的信息。 KMP算法 首先介绍的就是KMP 算法。 这个算法实在是太有名了,大学上的算法课程除了最笨的Brute Force 算法,然后就介绍了KMP 算法。也难怪,呵呵。谁让Knuth D.E. 这么world famous 呢,不仅拿了图灵奖,而且还写出了计算机界的Bible (业内人士一般简称TAOCP). 稍稍提一下,有个叫H.A.Simon的家伙,不仅拿了Turing Award ,顺手拿了个Nobel Economics Award ,做了AI 的爸爸,还是Chicago Univ的Politics PhD ,可谓全才。 KMP 的思想是这样的: 利用不匹配字符的前面那一段字符的最长前后缀来尽可能地跳过最大的距离 比如 模式串ababac这个时候我们发现在c 处不匹配,然后我们看c 前面那串字符串的最大相等前后缀,然后再来移动 下面的两个都是模式串,没有写出来匹配串 原始位置ababa c 移动之后aba bac 因为后缀是已经匹配了的,而前缀和后缀是相等的,所以直接把前缀移动到原来后缀处,再从原来的c 处,也就是现在的第二个b 处进行比较。这就是KMP 。 Horspool算法。 当然,有市场就有竞争,字符串匹配这么大一个市场,不可能让BF 和KMP 全部占了,于是又出现了几个强劲的对手。

KMP字符串模式匹配算法解释

个人觉得这篇文章是网上的介绍有关KMP算法更让人容易理解的文章了,确实说得很“详细”,耐心地把它看完肯定会有所收获的~~,另外有关模式函数值next[i]确实有很多版本啊,在另外一些面向对象的算法描述书中也有失效函数f(j)的说法,其实是一个意思,即next[j]=f(j-1)+1,不过还是next[j]这种表示法好理解啊: KMP字符串模式匹配详解 KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法。简单匹配算法的时间复杂度为O(m*n);KMP匹配算法。可以证明它的时间复杂度为O(m+n).。 一.简单匹配算法 先来看一个简单匹配算法的函数: int Index_BF ( char S [ ], char T [ ], int pos ) { /* 若串S 中从第pos(S 的下标0≤pos

字符串模式匹配

实验7、字符串查找 目的 掌握字符串模式匹配的经典算法。 问题描述 分别用简单方法和KMP方法实现index在文本串中查找指定字符串的功能。 步骤 1.定义字符串类型 2.实现简单的index操作,从文本串中查找指定字符串。 3.实现KMP方法的index操作,从文本串中查找指定字符串。 4.[选]建立一个文本文件,读入每一行来测试自己完成的练习,观察并理解程序的各 个处理。 设备和环境 PC计算机、Windows操作系统、C/C++开发环境 结论 能够理解和掌握字符串模式匹配的典型算法。 思考题 1.对KMP算法分别用手工和程序对某个模式串输出next和nextval。 朴素算法: #include #include #define NOTFOUND -1

#define ERROR -2 #define MAXLEN 100//字符串的最大长度 char S[MAXLEN+10],T[MAXLEN+10],st[MAXLEN+10];//串S和串T int S0,T0; //S0:串S的长度 T0:串T的长度 int pos; //pos的起始位置 void Init(char *S,int &S0)//读入字符串 { int len,i; New_Input: scanf("%s",st);//读入字符串 len=strlen(st); if (len>MAXLEN)//如果字符串的长度大于规定的字符串最大长度 { printf("This String is too long,Please Input a new one.nn"); goto New_Input;//重新读入字符串

字符串的模式匹配实验报告

实验题目:字符串的模式匹配 一、实验描述 用BF算法实现字符串的模式匹配 二、实验目的和任务 从主串的第pos位置字符开始和模式子串字符比较,如果相等,则继续逐个比较后续字符;否则从主串的下一个字符起再重新和模式子串的字符比较。直到找到匹配字符串或者是主串结尾。 三、概要设计 BF(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串P的第一个字符进行匹配,若相等,则继续比较S的第二个字符和P的第二个字符;若不相等,则比较S的第二个字符和P的第一个字符,依次比较下去,直到得出最后的匹配结果。 四、运行与测试 #include #include int BFMatch(char *s,char *p) { int i,j; i =0; while(i < strlen(s)) { j = 0; while(s[i] == p[j] &&j

{ char *szSource = "ababcababa"; char *szSub = "ababa"; int index =BFMatch(szSource, szSub); printf("目标串包含匹配串的起始位置:%d",index); } 五、运行结果 六、实验心得 通过这次课程设计,让我了解了字符串的定位操作即字符串模式匹配的基本概念和算法,探讨了字符串模式匹配操作的最基本的BF匹配算法。虽然看起来很简单的程序,做起来却遇到了不少问题,编程中出行了一些小错误,多次查改之后再进行修改,所以我觉得在以后的学习中,我会更加注重实践,注重多练,多积累。

《KMP 字符串模式匹配算法》教学课例

《KMP字符串模式匹配算法》教学课例 程玉胜 安庆师范学院计算机与信息学院 KMP字符串模式匹配是数据结构课程中一个重要的知识点,也是一个难点(学过KMP 算法的同学100%认为:KMP是数据结构课程中最难的部分)。为了消除他们对KMP算法学习的恐惧心理,激发他们的学习兴趣,调动其积极性,显得尤为重要。 基于以上,我们根据学生的认知特点和接受水平,对教材内容进行了重新构建,并按照数据结构中?时间复杂度?概念,增加了不同模式匹配算法的运行时间,动态逼真的显示了算法的?时间?性能,获得了较好的教学效果。 一、教学目标 知识目标:让学生了解KMP算法应用的普遍性。如:在目前众多的文字处理软件中得到广泛应用,如Microsoft Word中的?查找?或?替换?操作。而这种操作实现的机制,同学们特别是计算机专业的学生很少去想过。 能力目标:要求学生体验一个完整的抽象数据类型(ADT)的实现方法和过程,并学会判断、计算算法优劣的方法。 价值目标:消除恐怖的学习心态,让学生感悟数据结构算法实际应用价值,从而激发学习的兴趣,形成积极主动式学习的态度。 二、教材分析 使用教材是清华大学严蔚敏教授并由清华大学出版社出版的《数据结构(C语言版)》,该教材难度较大,其实验方法特别是ADT方法在教材中介绍较少,而且KMP算法更是从理论分析的角度介绍了匹配算法和next的计算,自学难度很大;虽然该节知识点属于?**(表示难度较大,可以不讲)?,但是其又是考研的一个热点,所以我们又不得不讲。 三、教学重点、难点 教学重点:KMP算法中的next和改进的nextval计算 教学难点:KMP算法中如何计算next值 四、教具准备 卡片:多个字符串,字符串指针 强力磁吸:6个 五、互动式教学过程

相关文档
最新文档