数据结构课件-串_第1页
数据结构课件-串_第2页
数据结构课件-串_第3页
数据结构课件-串_第4页
数据结构课件-串_第5页
已阅读5页,还剩32页未读 继续免费阅读

下载本文档

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

文档简介

第4章串(String)4.1串类型的定义4.2串的表示和实现4.3串的模式匹配算法4.1.1串的定义定义:串(string)是由零个或多个任意字符组成的字符序列,是数据元素为单个字符的特殊线性表。4.1串的类型定义说明:1)其中s是串名,用双引号括起来的字符序列是串的值。2)ai(1<=i<=n)可以是字母、数字或其他字符;n为串中字符的个数,称为串的长度,i是序号。

记为:

s=‘a1a2……..an’(n≥0)为何要单独讨论“串”类型?1)字符串操作比其他数据类型更复杂(如拷贝、连接操作)2)程序设计中,处理对象很多都是串类型。几个术语空串:长度为0的字符串;空格串:由空格字符组成的字符串,长度>1.子串:字符串中任意个连续的字符构成的序列;母串:包含该子串的字符串;两串相等:两个字符串的长度相等且各对应位置上的字符都相同.字符的位置:从1开始子串的位置:该子串第一个字符的位置例1:现有以下4个字符串:a=‘BEI’ b=‘JING’c=‘BEIJING’

d=‘BEIJING’问:①他们各自的长度?a是c和d的子串,在c和d中的位置都是1②a是哪个串的子串?在主串中的位置是多少?a=3,b=4,c=7,d=8

空串是任意串的子串;任意串S都是S本身的子串,除S本身外,S的其他子串称为S的真子串。③空串是哪个串的子串?

a是不是自己的子串?4.1.2串的基本运算1.求串的长度StrLength(s);2.串赋值StrAssign(s1,s2);3.两个串的连接StrConcat(s1,s2,s)或StrConcat(s1,s2)4.求某串的子串SubStr(s,i,len);5.串比较StrCmp(s1,s2);6.子串定位StrIndex(s,t);7.插入子串StrInsert(s,i,t);8.删除子串StrDelete(s,i,len);9.置换StrRep(s,t,r)。4.2 串的表示和实现定长顺序存储表示——用一组地址连续的存储单元存储串值的字符序列,属静态存储方式。堆分配存储表示——用一组地址连续的存储单元存储串值的字符序列,但存储空间是在程序执行过程中动态分配而得。串的块链存储表示——链式方式存储首先强调:串与线性表的运算有所不同,是以“串的整体”作为操作对象,例如查找某子串,在主串某位置上插入一个子串等。串有三种机内表示方法:顺序存储链式存储定长顺序存储特点:用一组连续的存储单元来存放串,直接使用定长的字符数组来定义,数组的上界预先给出,故称为静态存储分配。4.2.1定长顺序存储结构注:一般用下标为0的数组分量来存放串长信息(如pascal语言);C语言约定在串尾加结束符‘\0’,以利操作加速,但不计入串长(用首址和串长、或首址和尾标记来描述串数组)若字符串超过Maxstrlen

则自动截断(因为静态数组存不进去)。第一种:#defineMAXSIZE256chars[MAXSIZE];abefi0256cdgh13478\09MAXSIZE-1第二种:#defineMAXSIZE256chars[MAXSIZE+1];abefi0256cdgh1347899MAXSIZE

运算实现(采用第一种表示串长的方式)1.求串的长度StrLength(s);int

StrLength(chars[]){int

len=0;

while(s[len]!=‘\0’)len++;returnlen;}2.串赋值StrAssign(s1,s2);voidStrAssign(s1,s2)chars1[],s2[];{intj=0;while(s2[j]!=‘\0’){s1[j]=s2[j];j++;}s1[j]=‘\0’;}3.两个串的连接StrConcat(s,s1,s2)4.求某串的子串SubStr(s,i,len);5.串比较StrCmp(s1,s2);注:Concat操作=concatenation,把多个短字符串合并为长字符串复习:C语言中常用的串运算

C串比较:intstrcmp(char*s1,char*s2);

求串长:intstrlen(char*s);

串连接:charstrcat(char*to,char*from)

子串T定位:charstrchr(char*s,char*c);

……注:用C处理字符串时,要调用标准库函数#include<string.h>

类CStrCompare(S,T)StrLength(S)Concat(&T,S1,S2)Index(S,T,pos)Replace(&S,T,V)

用子串V替换子串T

设s=‘IAMASTUDENT’,

t=‘GOOD’,

q=‘WORKER’。求:例1:

StrLength(s)=

StrLength(t)=

SubString(&sub,

s,8,7)=

SubString(&sub,

t,2,1)=Index(s,‘A’)=Index(s,t)=Replace(&s,‘STUDENT",

q)=144‘STUDENT’‘O’30(s中没有t=‘GOOD’

!)Index(S,T,pos)

返回子串T在pos之后的位置‘IAMAWORKER’提问:当s=‘IAMASTUDENT’时,

INDEX(s,’A’,pos)=3,若想搜索后面那个‘A’怎么办?答:INDEX(s,’A’)返回的只是“第一次”出现的位置。如果还要搜索后面的A,则pos变量要跟着变才行。也就是说,要把得到的“第一次”位置再代入INDEX(s,’A’,pos)函数中循环操作才行。解:因为SubString(s,6,2)=’A’;SubString(s,7,8)=’STUDENT’Concat(,t,SubString(s,7,8))=’GOOD

STUDENT’所以:Concat(,SubString(s,6,2),Concat(t,SubString(s,7,8)))=’AGOODSTUDENT’例2:设s=‘IAMASTUDENT’,

t=‘GOOD’,求:

Concat(SubString(s,6,2),Concat(t,SubString(s,7,8)))=?4.2.2

堆存储结构基本思想:在内存中开辟能存储足够多的串、地址连续的存储空间作为应用程序只所有串的可利用存储空间,称为堆空间。(未分配区域)(已分配区域)思路:利用malloc函数合理预设串长空间。特点:

若在操作中串值改变,还可以利用realloc函数 按新串长度增加空间(即动态数组概念)。Typedefstruct{char*ch;//若非空串,按串长分配空间;否则ch=NULL

intlength;//串长度}HString堆分配存储特点:仍用一组连续的存储单元来存放串,但存储空间是在程序执行过程中动态分配而得。堆T的存储结构描述:T.chT.lengthC是指针变量,可以自增!意即每次后移一个数据单元。直到终值为“假”停止,串尾特征是c=‘\0’=NULL=0Status

StrAssign(HString

&T,char*chars){//生成一个串T,T值←串常量charsif(T.ch)free(T.ch);

//释放T原有空间

for(i=0,c=chars;c;++i,++c);//求chars的串长度i例1:编写建堆函数此处T.ch[0]没有用来装串长,因为另有T.length分量if(!i){T.ch=NULL;T.length=0;} else{ if(!(T.ch=(char*)malloc(i*sizeof(char)))) exit(OVERFLOW);

T.ch[0..i-1]=chars[0..i-1]; T.length=i; } ReturnOK;}//StrAssignStatus

StrInsert

(HString

&S,intpos,

HStringT){

//在串S的第pos个字符之前(包括尾部)插入串Tif(pos<1||pos>S.length+1)returnERROR;//pos不合法则告警

if(T.length){

//只要串T不空,就需要重新分配S空间,以便插入Tif(!(S.ch=(char*)realloc(S.ch,(S.length+T.length)*sizeof(char))))exit(OVERFLOW);//若开不了新空间,则退出

for(i=S.length-1;i>=pos-1;--i)S.ch[i+T.length]=S.ch[i];//

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

S.ch[pos-1…pos+T.length-2]=T.ch[0…T.length-1];

//插入T,略\0

S.length+=T.length;//刷新S串长度}returnOK;}//StrInsert例2:用“堆”方式编写串插入函数讨论:法1存储密度为

;方法2存储密度为

;显然,若数据元素很多,用方法2存储更优—称为块链结构链式存储特点:用链表存储串值,易插入和删除。方法1:链表结点的数据分量长度取1(个字符)方法2:链表结点(数据域)大小取n(例如n=4)1/29/15=3/5

A

B

C

I

NULLheadheadABCDEFGHI###NULL4.2.3链式存储结构对每个结点的描述#defineCHUNKSIZE80

//每块大小,可由用户定义typedefstructChunk{//首先定义结点类型

charch[CHUNKSIZE];

//每个结点中的数据域

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

块链类型定义:块链函数的编写略typedefstruct{//其次定义用链式存储的串类型

Chunk*head;//头指针

Chunk*tail;//尾指针

intcurLen;//结点个数

}LString;//串类型只用一次,前面可以不加Lstring对块链表的整体描述4.3

串的模式匹配算法设s和t是给定的两个串,在主串s中查找子串t的过程称为~。其中t也称为模式。为运算方便,字符串采用定长存储,且用第二种方式表示串长:#defineMAXSIZE256chars[MAXSIZE+1];abefi0256cdgh1347899MAXSIZE1.简单的模式匹配算法(BF算法)(1)算法思想:例:主串S:“acabaabaabcacaabc”

模式串t:“abaabcac”s:acabaabaabcacaabct:abaabcaci=1j=1s:acabaabaabcacaabct:abaabcaci=2j=2if(s[i]==t[j]){i++;j++;}if(s[i]!=t[j])

{i回溯到本趟开始的下一个;

j回溯到1;}s:acabaabaabcacaabct:abaabcaci=2j=1s:acabaabaabcacaabct:

abaabcaci=3j=1i=4j=2i=5j=3i=6j=4i=7j=5i=8j=6s:acabaabaabcacaabct:

abaabcaci=4j=1s:acabaabaabcacaabct:

abaabcaci=5j=1i=6j=2s:acabaabaabcacaabct:

abaabcaci=6j=1i=7j=2i=8j=3i=9j=4i=10j=5i=11j=6i=12j=7i=13j=8i=14j=9(2)算法实现循环条件?什么时候回溯?回溯时i、j如何计算?如何判断匹配是否成功?匹配成功时,返回的起始位置如何计算?2.改进后的模式匹配算法(KMP算法)s:acabaabaabcacaabct:

abaabcaci=8j=6s:acabaabaabcacaabct:

abaabcaci=8k=3(1)KMP算法思想:i不回溯,j也不是回溯到1,而是回溯到k,也就是模式t向右滑动到某个位置k。(2)k位置的确定——next函数用next函数来确定k的值,即k=next(j);next(j)=max{k|1<=k<j且”t1t2…tk-1”=”tj-k+1tj-k+2…tj-1”1其他情况0j=1以j=6时,求解next[6]为例计算过程如下:根据公式,0<k<6当k=1时,t1=“a”≠

t5=“b”;(不满足)当k=2时,t1t2=“ab”=t4t5=“ab”;(满足)当k=3时,t1t2t3=“aba”≠t3t4t5=“aab”;(不满足)当k=4时,t1t2t3t4=“abaa”≠t2t3t4t5=“baab”;(不满足)因为满足条件的k的最大值为2,故next[6]=3。j12345678模式串abaabcacnext(j)

例:求模式串“abaabcac”的next函数值12231201例:主串S:“aabcbabcaabcaababc”

模式串t:“abcaababc”j123456789模式串abcaababcnext[j]

011122323s:aabcbabcaabcaababct:abcaababci=1j=1i=2j=2s:aabcbabcaabcaababct:abcaababci=2j=1i=3j=2i=4j=3i=5j=4j123456789模式串abcaababcnext[j]

011122323s:aabcbabcaabcaababct:abcaababci=5j=1s:aabcbabcaabcaababct:

abcaababci=6j=1i=7j=2i=8j=3i=9j=4i=10j=5i=11j=6i=12j=7s:aabcbabcaabcaababct:

abcaababci=12j=3i=13j=4i=14j=5i=15j=6i=16j=7i=17j=8i=18j=9i=19j=10(3)KMP算法实现循环条件?什么时候回溯?回溯时i、j如何计算?如何判断匹配是否成功?匹配成功时,返回的起始位置如何计算?(4)如何求next函数next[1]=0;设next[i-1]=k,如何求next[i]?(令j=i)j123456789模式串abcabcdbcnext[j]0i=2j=1k=next[j]=01next(j)=max{k|1<=k<j且”t1t2…tk-1”=”tj-k+1tj-k+2…tj-1”1其他情况0j=1第一种情况:k==0next[i]=k+1;

第二种情况:t[k]==t[j]j123456789模式串abcabcdbcnext[j]011123i=6j=5next[i]=k+1;

k=2第三种情况:

t[k]≠t[j]

j123456789模式串abaababbanext[j]0112234i=8j=73(1)回溯k=next[k]直至t[j]==t[k]j123456789模式串abcabcdbcnext[j]0111234i=8j=71(2)回溯k=next[k]直至k==0k=4k=2k=4k=1k=0

温馨提示

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

评论

0/150

提交评论