计算机课件 串_第1页
计算机课件 串_第2页
计算机课件 串_第3页
计算机课件 串_第4页
计算机课件 串_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章串

学时:4学时

本章主要内容:

1.串的有关概念及ADT定义;

2.串的三种存储结构急主要操作算法实现;

3.串的两种匹配算法。

本章重点难点:

1.顺序串和堆串两种存储结构;

2.串的KMP匹配算法;

3.Next[j]和nextval[i]的计算

4.1串类型的定义

4.2串的表示和实现

4.3串的模式匹配算法

4.1串类型的定义

串即字符串,是由零个或多个字符组成的有限序列,

是数据元素为单个字符的特殊线性表。

记为:a」(n>0)

Tnr

串名串值(用''括起来

隐含结束符

‘\0"即

[ASCII码NUL,

若干术语:

串长:串中字符的个数(n>0).n=0时称为空串0。

空白串:由一个或多个空格符组成的串。

问:空串和空白串有无区别?

答:有区别。

空串(NullString)是指长度为零的串;

而空白串(BlankString),是指包含一个或多个空白

字符'9(空格键)的字符串.

子串:串S中任意个连续的字符序列叫S的子串。

子串位置:子串的第一个字符在主串中的序号。

字符位置:字符在串中的序号。

串相等:串长度相等,且对应位置上字符相等。

“空串是任意串的子串;任意串s都是S本身的子串,

除S本身外,S的其他子串称为S的真子串。”

串的抽象数据类型定义

ADTString{

Objects:D={ai|ai£CharacterSet,i=l,2V..,n,n>0}

Relations:Rl={<ai-l,ai>|ai-l,aiWD,i=2,・・.,n)

functions:

fStrAssign(&T,chars)〃串赋值,生成值为chars的串T

小StrCompare(S,T)〃串比较,若S>T,返回值大于。…

操StrLength(S)〃求串长,即返回串S中的元素个数

子Concat(&T,SI,S2)//串连接,用T返回S1+S2的新串

集SubString(&Sub,S,pos,len)//求S中pos起长度为len的子串

Index(S,T,pos)//子串定位函数(模式匹配),返回位置

Replace(&S,T,V)〃用子串V替换子串T

}ADTString

例1:设s=UAMASTUDENT%t='GOOD',

q='WORKER'。求:

StrLength(s)=14//返回子串T在pos

->U弘Q要

StrLength(t)=4

SubString(&sub,s,8,7)='STUDE

SubString(&sub,t,2,1)=OReplace(&S5T,V)

//用子串V换子串T

Index(s,6A5)=3

Index(s,t)=0(s中没有

Replace(&s「STUDENT',q)=qAMAWORKER9

问题:当sAMASTUDEN「时,

INDEX(s,'A',pos)=3,若想搜索后面那个N

怎么办?

解答:INDEX(s,返回的只是“第一次”出现

的位置。

如果还要搜索后面的A,贝》pos变量要跟着变才行。

也就是说,要把得到的“第一次”位置再代入INDEX

(sJA"pos)函数中循环操作才行。

4.2串的表示和实现

首先强调:串与线性表的运算有所不同,是以“串的整体”作

为操作对象,例如查找某子串,在主串某位置上插入一个子串

等。串有三种机内表示方法:

•定长顺序存储表示

顺序J——用一组地址连续的存储单元存储串值的字

存储符序列,属静态存储方式。

堆分配存储表示

----用一组地址连续的存储单元存储串值的字

符序列,但存储空间是在程序执行过程中动态

分配而得。

链式■串的块链存储表示

存储——链式方式存储

定长顺序存储特点:用一组连续的存储单元来存放串,

直接使用定长的字符数组来定义,数组的上界预先给出,

故称为静态存储分配。

例如:

#defineMaxstrlen255//用户可用的最大串长

typedefunsignedcharSString[Maxstrlen+1];

SStrings;//s是一个可容纳255个字符的顺序串。

注:

•一般用SString[O]来存放串长信息(如pascal语言);

•C语言约定在串尾加结束符6\0\以利操作加速,但不

计入串长

•若字符串超过Maxstrlen则自动截断。

例:用顺序存储方式编写求子串函数SubString(&Sub,S,pos,len)

poslen

StatusSubString(SString&sub9SStringS,intpos,intlen)

{if(pos<l||pos>S[0]||len<0||len>S[0]-pos+l)returnERROR;

//若pos和len参数越界,则告警

Sub[l.......len]=S[pos.......pos+len-1];

Sub[01=len:returnOK:

讨论:想存放超长字符串怎么办?

改用动态分配的一维数组----

堆分配存储特点:仍用一组连续的存储单元来存放串,

但存储空间是在程序执行过程中动态分配而得。

思路:利用malloc函数合理预设串长空间。

特点:若在操作中串值改变,还可以利用realloc函数

按新串长度增加空间(即动态数组概念)。

堆T的存储结构描述:

Typedefstruct{

char*ch;//若非空串,按串长分配空间;否则ch=NULL

intlength;〃串长度____________

}HString.T.ch

■T.length

泰山学院

例1:久建堆函数

StatusStrAssign(HString&T,char*chars)C是指针变量,可以自增!

事即每次后移一个数据单

{//生成一个串T,T值一串常量charyGo

if(T.ch)free(T.ch);空间

for(i=0,c=chars;;++k++c);//求chars的串长度i

if(!i){T.ch=NULL;T.length=0;

else{

if(!(T.ch=(charw)malloc(i*sizeof(char))))

exit(OVERFLOW);

T.ch[0..i-l]=chars[0・・i.m此处T.ch[0]没有

用来装串长,因为

T.length=i;另有T.length分

}

returnOK;

例2:।用“堆”方式编写串插入函数

StatusStrinsert(HString&S,intpos,HStringT)

{//在串S的第pos个字符之前(包括尾部)插入串T

if(pos<l||pos>S.length+l)returnERROR;//pos不合法则告警

if(T.length){//只要串T不空,就需要重新分配S空间,以便插入T

if(!(S.ch=(char*)realloc(S.ch,(S.length+T.length)*sizeof(char))))

exit(OVERFLOW);//若开不了新空间,则退出

for(i=S.length-l;i>=pos-l;—i)S.ch[i+T.length]=S.chfi];

//为插入T而腾出pos之后的位置,即从S的pos位置起全部字符均后移

S.ch[pos-1...pos+T.length-2]=T.ch[O...T.length-l];//插入T,略/0

S.length+=T.length;//刷新S串长度

}returnOK;

}//Strinsert

泰山学院

链式存储特点:用链表存储串值,易插入和删除。

法L链表结点的数据分量长度取1(个字符)

A17------'IBI7--------"ICIT-----------HINULL

法2:链表结点(数据域)大小取n(例如n二4)

head一^ABCD”-------7FGH•——,I###NULL

讨论:法1存储密度为"2;法2存储密度为9〃5=3/5,

显然,若数据元素很多,用法2存储更优一称为块链结构

块链类型的定义

typedefstruct{〃其次定义用链式存储的串类型

Chunk*head;//头指针

Chunk气ail;//尾指针

intcurLen;//结点个数

}Lstring;//串类型只用一次,前面可以不加Lstring

#defineCHUNKSIZE80〃每块大小,可由用户定义

typedefstructChunk{//首先定义结点类型

charch[CHUNKSIZE];//每个结点中的数据域

structChunk*next;//每个结点中的指针域

}Chunk;

4.3串的模式匹配算法

算法目的:确定主串中所含子串第一次出现的位置(定位)

定位问题称为串的模式匹配(PatternMatching),即子串定位运

算,它是串处理系统中最重要的操作之一。

典型函数为Index(S,T,pos).

算法种类:

•BF算法(又称古典的、经典的、朴素的、穷举的)

•KMP算?

单回溯,速度慢1

避免回溯,匹配速度快,

BF算法的实现一即编写Index(S,T,pos)函数

例1:S=6ababcabcacbab5,T=6abcac\pos=l,

求:串T在串S中第pos个字符之后的位置。

BF算法设计思想:

•将主串S的第pos个字符和模式T的第1个字符比较,

若相等,继续逐个比较后续字符;

若不等,从主串S的下一字符(pos+1)起,重新与T第一

个字符比较。

•直到主串S的一个连续子串字符序列与模式T相等。返回值

为S中与T匹配的子序列第一个字符的序号,即匹配成功。

否则,匹配失败,返回值0.

例2:S=6ababcabcacbab5,T=6abcac\求Index(S,T,5)

Intidt(SStringS,SStringT,intpos){\[pos=5|

i=pos;j=l;S=6ababcabcacbab9

while(i<=S[0]&&j<=T[0]){丁二'斗bca

if(S[i]==T[j]){++i,++j}〃继续比较后续字符J

else{i=i-j+24j=l;}〃指针回溯至U下一首位,重新开始匹配

if(j>T[OJ)returni-T[OJ;〃子串结束,说明匹配成功

elsereturnO;

}//Index匹配成功后指针仍要回溯!因为要返回的

是被匹配的首个字符位置。

BF算法的时间复杂度

讨论:

若n为主串长度,为子串长度,则串的BF匹配算法最坏的情

况下需要比较字符的总次数为=O(n*m)

一般的情况是:O(n+m)

推导方法:要从最好到最坏情况统计总的比较次

数,然后取平均。为了解决这样的情况,出现了更

加优化的算法:

请看KMP算法!

KMP算法(特点:速度快)

①KMP算法设计思想

②KMP算法的推导过程

③KMP算法的实现(关键技术:计算next[j])

④KMP算法的时间复杂度

kMP算法

KMP算法的时间复杂度可以达到O(m+n)。

定义:模式串的next函数

fo当j=1时〕

Max{k|1<k<j

next[j]二1\

且'P1P2…Pk-l'='Pj-k+l…Pj/}

1其它情况

intIndexKMP(SStringS,SStringT,intpos){

//1<pos<StrLength(S)

i=pos;j=1;

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

if(j=O||S[i]==

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论