算法设计B10040101Word文档下载推荐.docx

上传人:b****5 文档编号:16296002 上传时间:2022-11-22 格式:DOCX 页数:21 大小:350.76KB
下载 相关 举报
算法设计B10040101Word文档下载推荐.docx_第1页
第1页 / 共21页
算法设计B10040101Word文档下载推荐.docx_第2页
第2页 / 共21页
算法设计B10040101Word文档下载推荐.docx_第3页
第3页 / 共21页
算法设计B10040101Word文档下载推荐.docx_第4页
第4页 / 共21页
算法设计B10040101Word文档下载推荐.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

算法设计B10040101Word文档下载推荐.docx

《算法设计B10040101Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《算法设计B10040101Word文档下载推荐.docx(21页珍藏版)》请在冰豆网上搜索。

算法设计B10040101Word文档下载推荐.docx

理解模式匹配的含义,掌握简单匹配算法及模式匹配KMP算法的思想,实现以下任务:

(1)编程动态实现简单模式匹配算法及模式匹配KMP算法;

(2)根据给定的主串与模式串,给出根据两种匹配算法进行匹配的各趟匹配结果;

(3)测试用例:

主串:

ThrougharetrospectivelookatthemathematicsteachingatUSTC,thisarticlesummarizesuniversity’steachingachievementsinpast45years.

匹配子串:

teaching

输出结果:

匹配子串teaching出现在主串中的次数为2

2次的匹配的位置分别是:

48104;

(4)一个应用实例如下:

●要求编写建立一个文本文件,每个单词不包括空格且不跨行,单词由字符序列构成,且区分大小写;

●统计给定单词在文本中出现的总次数;

检索出某个单词在文本中的行号、在该行中出现的次数及位置。

二.课题内容和要求

本题主要是要掌握模式匹配的含义,以及KMP模式匹配算法相比简单模式匹配算法优越性。

模式匹配是指有两个串S和P,在串S中找P的过程。

其中S是主串,P是模式串。

简单匹配算法是从主串S中下标i的字符与模式串P的第1个字符开始逐个比较,遇到不相等时,即达到失配点,该趟匹配失败,S回到原来的i+1的位置,P回到第1个字符位置,继续下一趟匹配,直到匹配成功。

简单模式匹配算法效率不高,原因在于匹配过程中有回溯。

而KMP算法中,i只进不退,对串S来说就消除了回退。

本课题要求用简单模式匹配和KMP模式匹配分别来测试用例:

ThrougharetrospectivelookatthemathematicsteachingatUSTC,thisarticlesummarizesuniversity’steachingachievementsinpast45years.其中模式串是:

teaching,经过测试后都应该得到的结果是:

匹配子串teaching出现在主串中的次数为2,2次的匹配的位置分别是:

46102;

如果加入一个能计算时间的函数后,应该得到的结果是用简单模式匹配的时间比KMP模式匹配运行的时间长。

由此,就可以得到在测试样例较多的情况下选用算法会节省时间,这对一些项目来说是很重要的,就突出了KMP算法的优越性。

在课题要求中的应用实例中,要求1.建立一个文本文件,要求编写建立一个文本文件,每个单词不包括空格且不跨行,单词由字符序列构成,且区分大小写;

2.编写程序能够读入文本文件中的内容,运用已经写好的程序统计给定单词在文本中出现的总次数;

3.能够检索出某个单词在文本中的行号、在该行中出现的次数及位置。

KMP算法也有优化的地方。

在此,我又将改进的KMP算法也写进去了,三种方法可以放在一起比较,找出最优化的算法。

三.需求分析

1.实现简单模式匹配的函数,其中公有函数Find(String&

p)调用私有函数Find(int

i,String&

p),私有函数每次在主串中找出一个模式串,而公有函数可以计算出所有的模式串的个数和位置。

intString:

:

Find(inti,String&

P)//代码具体见详细设计

Find(String&

P)//代码具体见详细设计

2.实现KMP模式匹配的函数,其中公有函数KMPFind(String&

p)调用私有函数KMPFind(inti,String&

KMPFind(inti,String&

KMPFind(String&

3.实现改进的KMP模式匹配的函数,其中公有函数KMPFindImprove(String&

p)调用私有函数KMPFindImprove(inti,String&

KMPFindImprove(inti,String&

KMPFindImprove(String&

4.经过比较后改进的KMP算法是最优化的,所以在读取文件、测试文件时采用该进的KMP算法来做。

其中取文件的函数Read()要自己设计

voidString:

Read(char*file)//代码具体见详细设计

5.main()函数中做了一个菜单,可以根据不同的选择测试不同的功能。

四.设计概要

1.程序的算法设计说明,采用流程图形式

2.每个程序中使用的存储结构设计说明

因为采用的是面向对象C++的方法,定义了一个String类,其String类中成员变量和成员函数原型声明如下:

classString

{

Private:

intn;

char*str;

int*count;

//记录子串在主串中出现的位置

intFind(inti,String&

P);

//简单匹配算法找到最近的匹配串后立即停止,而不向下继续且缺乏一个数组记录位置

intfail();

//记录失败函数

voidFail();

intKMPFind(inti,String&

voidImproveFail();

//改进的失败函数

intKMPFindImprove(inti,String&

public:

String();

//建立一个空串

String(constchar*p);

String(constString&

p);

//拷贝函数

~String();

intLength(){returnn;

};

//返回当前串对象长度

voidOutput(){cout<

<

str;

//输出字符串

intFind(String&

//简单匹配算法

intKMPFind(String&

//KMP匹配算法

intKMPFindImprove(String&

//改进的KMP匹配算法

voidOutput2();

//输出子串在主串中出现的位置

voidOutput3();

//输出子串所在行数,位置及总个数

voidRead(char*);

各个功能段均采用数组的存储结构。

五.详细设计

#include<

iostream>

string>

fstream>

cstdlib>

time.h>

usingnamespacestd;

#defineMAX100000

#defineM69

private:

int*f();

//建立一个空串

String:

String()//无参数的构造函数进行初始化

n=0;

str=NULL;

count=NULL;

f=NULL;

}

String(constchar*p)//有参数的构造函数

n=strlen(p);

str=newchar[n+1];

strcpy(str,p);

count=newint[n];

for(inti=0;

i<

n;

i++)

count[i]=0;

f=newint[n];

for(intj=0;

j<

j++)

f[j]=-1;

p)//拷贝构造函数

n=p.n;

if(str==NULL)exit

(1);

str[i]=p.str[i];

str[n]='

\0'

;

//结束标识符'

,否则会出现乱码

count=newint[n];

count[j]=p.count[j];

for(intk=0;

k<

k++)

f[k]=p.count[k];

~String()

delete[]str;

P)//简单匹配算法i为主串P的位置,开始置0

if(i<

0||i>

n-1)//越界检查

cout<

"

Outofbounds!

endl;

return-1;

char*pp=P.str;

//模式串指针pp指向第一个字符

char*t=str+i;

//主串指针t指向下标i的字符

while(*pp!

='

\x0'

&

&

i<

=n-P.n)//子串pp未到串尾且剩余字符超过模式串长,则循环

if(*pp++!

=*t++)

pp=P.str;

//模式串回到第一个字符

t=str+(++i);

//主串回到i+1的位置

if(*pp=='

returni;

//若pp已到串尾,则匹配成功

P)

intsum=0;

intj=Find(0,P);

//共有find函数调用私有函数find

while(j!

=-1)

count[sum]=j;

sum++;

//count记录位置,sum记录次数

if(j<

=n-P.n)

j=Find(j+P.n,P);

}

returnsum;

Fail()//失败函数

{

intj=0,k=-1;

f[0]=-1;

while(j<

n)

if((k==-1)||(str[j]==str[k]))

j++;

k++;

//k==-1或str[j]==str[k]时,j,k各扩展1位,j无回溯

f[j]=k;

//求得的k存入f[j]

elsek=f[k];

//str[j]不等于str[k]时,k回溯到f[k]

if(i<

this->

Fail();

intj=0,m=P.n;

while(i<

n&

j<

m)

if(j==-1||str[i]==P.str[j])//相等或j=-1时,i、j均后移1个位置

i++;

else

j=P.f[j];

//到达失配点,j回溯到f[j]

return((j==m)?

i-m:

-1);

P)

intj=KMPFind(0,P);

j=KMPFind(j+P.n,P);

returnsum;

ImproveFail()//改进的失败函数

if((k==-1)||(str[j]==str[k]))//当k=-1或str[j]=str[k]时,j,k各扩展1位

k++;

if(str[j]==str[k])//将字符pk与pj比较,若相等则将f[k]存入f[j]

f[j]=f[k];

//否则将k存入f[j]

else

k=f[k];

//str[j]不等于str[k]时,k回溯到f[k],j无回溯

n-1)

ImproveFail();

if(j==-1||str[i]==P.str[j])

}

intj=KMPFindImprove(0,P);

{

count[sum++]=j;

=n-P.n)j=KMPFindImprove(j+P.n,P);

Read(char*file)//通过文件读取

charch;

char*temp=newchar[MAX];

inti=0;

ifstreaminfile(file);

if(!

file)//判断能否打开

Cannotopenthefile!

return;

while(infile.get(ch)!

="

#"

temp[i++]=ch;

if(ch=='

#'

)//以#为结束标志

break;

temp[i]='

n=i;

str=newchar[n];

//由于定义一个空子串时n=0,count,f等都为NULL,所以此处要重新定义

for(intz=0;

z<

z++)

str[z]=temp[z];

count[k]=0;

for(intj=0;

infile.close();

delete[]temp;

Output2()//输出子串在主串中的位置

while(count[i]!

=count[i+1]&

MAX-1)//若不再有新的子串匹配,则count[i]与count[i+1]均为0

count[i]<

"

Output3()//输出子串在文件中的行数、位置、及次数

intt=0;

int*line=newint[MAX];

//记录字符串在该行出现的次数

int*ram=newint[M];

//记录字符串在该行出现的位置

for(intm=1;

m<

=MAX;

m++)

line[m]=0;

for(intn=1;

n<

=M;

n++)

ram[n]=0;

MAX-1)

intl1=count[i]/M+1;

intl2=count[i+1]/M+1;

//记录相邻两个字符串行数(要考虑到只有一行的情况)

intr=count[i]%M;

//记录该字符串位置

line[l1]++;

ram[t++]=r;

if((l1!

=l2&

count[i+1]>

0)||(l1==l2&

count[i+1]==0))//换行

该单词在第"

l1<

行出现"

line[l1]<

次,"

分别在位置:

for(ints=0;

s<

t;

s++)

ram[s]<

//每行中出现的位置

t=0;

//到下一行找

voidmain()

intchoise=0;

cout<

******************************************************"

##1.简单模式匹配做测试样例##"

##2.KMP模式匹配做测试样例##"

##3.改进的KMP模式匹配做测试样例##"

##4.从文本测试函数##"

##5.返回##"

while(choise!

=5){

cin>

>

choise;

if(choise==1){//简单模式匹配算法测试

clock_tstart,finish;

start=clock();

Strings1("

ThrougharetrospectivelookatthemathematicsteachingatUSTC,thisarticlesummarizesuniversity’steachingachievementsinpast45years."

);

s1.Output();

Strings2("

teaching"

intm=s1.Find(s2);

用简单模式匹配测匹配子串"

s2.Output();

出现在主串中的次数为:

if(m!

=0)

{

次的匹配的位置分别是:

s1.Output2();

finish=clock();

endl<

timeis:

(double)(finish-start)/CLK_TCK<

if(choise==2)//KMP模式匹配算法测试

{

clock_tstart,finish;

ThrougharetrospectivelookatthemathematicsteachingatUSTC,thisarticlesummarizesuniversity’steachingachievementsinpast45years."

用kmp模式匹配测匹配子串:

intn=s1.KMPFind(s2);

if(n!

s1.Output2();

if(choise==3)//改进的KMP模式匹配算法测试

start=clock

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

当前位置:首页 > 表格模板 > 合同协议

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

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