数据结构第04章 串.docx
- 文档编号:26700573
- 上传时间:2023-06-21
- 格式:DOCX
- 页数:23
- 大小:26.18KB
数据结构第04章 串.docx
《数据结构第04章 串.docx》由会员分享,可在线阅读,更多相关《数据结构第04章 串.docx(23页珍藏版)》请在冰豆网上搜索。
数据结构第04章串
第四章串
教学目的与要求
本章目的是介绍串的逻辑结构、存储结构及其串上的基本运算。
重点和难点
本章重点是掌握串上实现的模式匹配算法,其也是本章难点。
教学内容
第一节 串的基本概念
4.1.1基本概念
串:
是零个或多个字符组成的有限序列。
串中所包含的字符个数称为串的长度。
空串:
长度为0的串称为空串,它不包含任何字符。
空白串:
仅由一个或多个空格组成的串称为空白串。
应注意空串和空白串的区别。
子串、主串:
串中任意个连续字符组成的子序列称为该串的子串,包含子串的串相应地称为主串。
空串是任意串的子串,任意串是其自身的子串。
子串在主串中的位置:
通常,将子串在主串中首次出现时子串首字符对应的主串中的序号定义为子串在主串中的位置。
2.串的基本运算
(1)求串的长度(Length)
(2)串复制(Copy):
(3)串联接(Concat)
(4)串比较(Compare)
(5)字符定位(Index)
除上述基本运算外,串运算还有求子串、子串的定位、子串的置换等操作。
这些操作,一般可由这些基本操作实现。
第二节 串的存储结构
4.2.1串的顺序存储
1.静态存储分配的顺序串
顺序串最简单的描述形式是直接使用定长的字符数组来定义。
其定义形式为
#definemaxstrsize256
typedefcharSeqstring[maxstrsise];
利用类型描述符Seqstrsring可定义数组变量存储串,利用特定字符表示串的结束(C语言用转义字符’\0’)。
例如Seqstrstrings;变量s可存储长度不超过255个字符的字符串,以’\0’作为串的结束。
顺序串的类型定义也可以象线性表的顺序存储一样,在定义字符数组的基础上,引入描述长度的成员。
其定义形式为
#definemaxstrsize256
typedefstruct{
charch[maxstrsise];
intlength;
}Sqestring;
(2)动态存储分配的顺序串(堆)
上述两种方式的共同缺点是主串值的存储空间是静态分配的是定长的。
动态分配则克服了上述缺点,其余定义形式为
typedefstruct{
char*ch;
intlength;
}Hstring;
成员ch为指针型,若串非空,按实际需要动态分配存储空间,ch指向其起始地址,否则ch为FULL。
成员length存储串长度。
(3)串的链式存储
用单链表的方式来存储串值,就是串的链式存储,简称为链串。
每个结点可以存储一个字符(数据域data为字符型),也可以存储多个字符(数据域data定义为字符型数组)。
3.基本运算的实现
串匹配算法很多,这里只讨论的是一种简单的朴素的串匹配算法。
在串匹配中,一般将主串称为目标(串),子串称为模式(串)。
设T为目标串,设P为模式串。
串匹配实际上是对合法的位置0≤i≤n-m,依次将目标串中的子串T[i..i+m-1]和模式串P[0..m-1]进行比较,若相等,则称从位置i开始的匹配成功,否则,则称从位置i开始的匹配失败。
位置i称为位移,匹配成功时,位置i称为有效位移,匹配失败时,位置i称为无效位移。
(1)顺序串上的子串的定位运算(模式匹配)
算法思想:
通过一个循环依次检查n-m+1个合法的位移i(0≤i≤n-m)是否为有效位移。
i初值为0,终值为n-m,其确定了目标串中子串的起始位置,每趟匹配结束后通过i值加1(i++)使i指向下一合法位移。
C语言算法:
Intnaivestrmatch(SeqstringT,SeqstringP)
{//查找模式P在目标T中首次出现位置,成功时返回有效位移i,失败返回-1
inti,j,k;
intm=P.length,n=T.length;//模式和目标串的长度
for(i=0;i<=n-m;i++)//循环控制匹配的趟数,其由合法位移的个数确定
{j=0;k=i;//确定模式串起始位置j、目标串动中子串的起始位置k,即合法位移i
while(j {k++;j++;} if(j==m)//退出while循环若j==m说明匹配成功 return(i); } return–1;//退出外循环,说明没有有效位移,匹配失败 } 算法时间复杂度为O(n-m+1)m) (2)链串上的子串的定位运算(模式匹配) 算法思想: 算法思想与顺序串上的子串的定位运算完全相同。 但应注意,存储结构不同将导致算法实现时具体操作的不同。 C语言算法: Linkstrnode*linkstrmatch(LinkstringT,LinkstringP) {//查找模式P在目标T中首次出现位置,成功时返回有效位移shift,失败返回NULL Linkstrnode*shift,*t1,*p1; Shift=T; t1=shift;p1=P;//工作变量初始设置t1指向子串的起始位置,p1指向模式的起始位置 while(t1&&p1)//循环控制匹配p1为NULL匹配成功,t1为NULL且p1不为NULL匹配失败 {if(t1->data==p1->data) {t1=t1->next;p1=p1->next;} else {shift=shift->next;t1=shift;p1=P;} }//对应结点字符相等,t1,p1后移指向下一结点,否则,合法位移shift后移指向下一子串,t1、p1重新定位开始下趟匹配。 if(p1==NULL) returnshift; else returnNULL; }//退出循环后,判定匹配成功与否 算法时间复杂度与顺序串上的子串的定位运算相同。 分析: 顺序串和链串上实现串的模式匹配,算法思想相同,但应注意,存储结构不同所导致的算法实现时具体操作上的区别。 在顺序串上位移为整数,链串上位移为结点的地址;子串与模式匹配时工作变量后移在顺序串上通过加1实现,链串上靠指针变量后移实现;匹配成功与否的判令条件顺序串上为j==m,链串上为p==NULL。 对于不同的存储结构能够写出算法这是学习数据结构的基本要求,改变存储结构要求应写出算法这也是一个重点。 这一点大家应给予足够的重视。 应用举例 算法阅读题 1.下列算法的功能是比较两个链串的大小,其返回值为: -1s1 comstr(s1,s2)=0s1=s2 1s1>s2 请在空白处填入适当的内容。 〖2001〗 intcomstr(linkstrings1,linkstrings2) {//s1和s2为两个链串的头指针 while(s1&&s2){ if(s1->data if(s1->data>s2->data)return1; ① ② } if(③)return–1; if(④)return1; ⑤; } 〖分析〗该题考核点是串的比较操作。 While型循环通过指针s1、s2将两个串中字符逐一比较,若发现不等字符,则不等字符的大小就是两个串的大小;若所比较字符均相等,直到有串被扫描完为止,退出循环。 然后判断,若某个串未被扫描完,则其值大,若两个串同时被扫描完,则两个串相等。 〖答案〗① s1=s1->next;②s2=s2->next;③s2(或s2! =NULL)④s1(或s1! =NULL)⑤return0 2.编写算法实现现两个串的连接。 算法如下: voidstringcat(HstringS,HstringT) {char*p,*q; p=S.ch+S.length; q=t.ch; while(p *p++=*q++; if(q elseS.length=S.lengh+T.length; } 3.删除主串中所有指定子串。 算法如下: voiddelsubstring(HstringS,HstringT) {inti=0,j,k; while(i {for(j=i,k=0;k if(S.ch[j]! =T.ch[k]) break; if(k>=T.length) {while(j {S.ch[j-T.length]=S.ch[j]; j++;} S.length=S.length-T.length;} else i++; } } 【历届试题分析】 一、选择题 1.下所述中正确的是()〖2001〗 A.串是一种特殊的线性表B. 串的长度必须大于零 C.串中元素只能是字母 D.空串就是空白串 〖答案〗A 2.若目标串的长度为n,模式串的长度为[n/3],则执行模式匹配算法时,在最坏情况下的时间复杂度是( )〖2001〗 A.O(n/3) B.O(n) C.O(n2) D.O(n3) 〖分析〗最坏情况下模式匹配的时间复杂度为O((n-[n/3]+1)*[n/3]),由于n和[n/3]是同阶的,所以,时间复杂度可写为O(n2)。 〖答案〗C 3.设有两个串T和P,求P在T中首次出现的位置的串运算称作( )〖2003〗 A.联接 B.求子串 C.字符定位 D.子串定位 〖分析〗该题考核点是串的基本操作。 〖答案〗D 4.为查找某一特定单词在文本中出现的位置,可应用的串运算是( )〖2002〗 A.插入 B.删除 C.串联接 D.子串定位 〖答案〗D 5.已知函数Sub(s,i,j)的功能是返回串s中从第i个字符起长度为j的子串,函数Scopy(s,t)的功能为复制串t到s。 若字符串S="SCIENCESTUDY",则调用函数Scopy(P,Sub(S,1,7))后得到( )〖2002〗 A.P="SCIENCE" B.P="STUDY" C.S="SCIENCE" D.S="STUDY" 〖分析〗该题考核点是串的基本操作,函数Scopy(P,Sub(S,1,7))将串中子串″SCIENCE″复制到P中,而串S值未变。 正确答案为A。 〖答案〗A 二、填空题 6.在串S="structure"中,以t为首字符的子串有 12 个。 〖2001〗 〖分析〗该题考核点是子串的概念。 其中存在两个长度为1的子串。 〖答案〗12 7.串S="Iamaworker"的长度是________。 〖2002〗 〖分析〗该题考核点是串长度的概念。 〖答案〗13 8.设S1="good",S2=" ",S3="book",则S1,S2和S3依次联接后的结果是____________。 〖2003〗 〖分析〗该题考核点是串的连接操作及空白串的概念。 〖答案〗"good book" 三、算法阅读题 9.下列算法的功能是比较两个链串的大小,其返回值为: -1s1 comstr(s1,s2)=0s1=s2 1s1>s2 请在空白处填入适当的内容。 〖2001〗 intcomstr(linkstrings1,linkstrings2) {//s1和s2为两个链串的头指针 while(s1&&s2){ if(s1->data if(s1->data>s2->data)return1; ① ② } if(③)return–1; if(④)return1; ⑤; } 〖分析〗该题考核点是串的比较操作。 While型循环通过指针s1、s2将两个串中字符逐一比较,若发现不等字符,则不等字符的大小就是两个串的大小;若所比较字符均相等,直到有串被扫描完为止,退出循环。 然后判断,若某个串未被扫描完,则其值大,若两个串同时被扫描完,则两个串相等。 〖答案〗① s1=s1->next;②s2=s2->next;③s2(或s2! =NULL)④s1(或s1! =NULL)⑤return0 同步练习题 一、选择题 1.下列有关字符串的描述,正确的是(A) A.字符串是0个或多个字符构成的有限序列; B.字符串是0个或多个字母不同的有限序列; C.字符串中最少要有一个子符; D.字符串中不能有空格字符。 2.字符串S="string"中,包含的子串的个数是(C)(空串) A.20B.21C.22D.23 3.目标串为T="thisisastring",模式串P="string",进行模式匹配,有效位移是(C)(起始位置为0)。 A.9B.10C.11D.12 4.已知串S="string",T="this",执行运算strlen(strcopy(S,T))的结果是(A) A.4B.6C.10D.2 5.目标串为T="thisisastring",模式串P="string",进行模式匹配,所有的无效位移数是(B) A.6B.10C.16D.11 6.下列命题正确的是(C) A.空串就是空白串;B.空串不是串; C.空串是长度为0的字符串D.串相等指的是长度相等 7.若字符串采用链式存储,每个字符占用一个字节,每个指针在占用四个字节,则该字符串的存储密度为(D) A.50%B.25%C.75%D.20% 8.当目标串的长度为n,模式串的长度为m时,朴素的模式匹配算法最坏情况下字符的比较次数(C) A.nB.n*mC.(n-m+1)*mD.m 9.当目,模式串的长度为m时,朴素的模式匹配算法最好情况下字符的比较次数(B) A.nB.mC.n+mDn-m 10.字符串是一种特殊的线性表,它与一般线性表的区别是() A.字符串是一种线性结构; B.字符串可以进行复制操作; C.字符串由字符构成并且通常作为整体参与操作; D.字符串可以顺序存储也可以链式存储。 二、填空题 1.空串的长度为0,空格串(空白串)的长度为空格数。 2.子串的定位运算又称为,通常把主串又称为目标子串又称为模式。 3.成功匹配的起始位置称为有效位移,匹配失败的起始位置称为无效位移。 4.设目标串为T="abccdadeef",模式串P="ade",则第6趟匹配成功。 5.已知串T="abccdadeef",P="abccyde",函数strcmp(T,P)的运算结果是<0。 6.串朴素的模式匹配算法在顺序串和链串上运行,时间复杂度o(m+n)。 7.已知串T="abccdadeef",T中包含以b打头的子串有9个。 8.通常在程序设计中,串分为串常量和串变量。 9.按存储结构通常分为顺序和链式。 10.设s1="GOOD",s2=" ",s3="BYE! ",则s1,s2,和s3连接后的结果是。 三.阅读程序题 1.指出程序功能 intstringcmp(HstringS,HstringT) {inti=0,tag=1; if(S.length! =T.length)tag=0; else while(i if(S.ch[i]==T.ch[i])i++; elsetag=0; returntag; } 2.阅读程序 intstringpatindex(HstringS,HstringT) {inti,j,k; for(i=0;i {for(j=i,k=0;k if(S.ch[j]! =T.ch[k]&&|T[k]! ='? ') break; if(k>=T.length)returni; } return–1; } (1)指出程序功能; (2)设S中存储"thereareastring",T中存储"? ? r"函数的返回值是什么? 3.阅读程序指出程序功能 voidrestring(HstringS) {char*p,*q,c; p=S.ch;q=S.ch+S.length-1; while(p {c=*p;*p=*q;*q=c; p++;q--; } } 四、程序设计题 1.编写算法实现两个串的连接。 2.设计算法删除主串中所有指定子串 3.编写算法判断串是否为回文 同步练习题答案 一、选择题 1.A2.C 3.C 4.A 5.B 6.C 7.D 8.C 9.B 10.C 二、填空题 1.0,包含空格的的数;2.模式匹配,目标串,模式串;3.有效位移,无效位移; 4.6; 5.<0; 6.O(m+n);7.9; 8.串常量,串变量; 9.顺序串,链串; 10.GOODBYE! 三.阅读程序题 1.【答案】判断两个串是否相等,若相等返回1,否则返回0。 2.【答案】 (1)带通配符? 的子串定位函数; (2)返回值为1。 3.【答案】将一个串逆置。 四、程序设计题 4.实现两个串的连接算法: voidstringcat(HstringS,HstringT) {char*p,*q; p=S.ch+S.length; q=t.ch; while(p *p++=*q++; if(q elseS.length=S.lengh+T.length; } 5.删除主串中所有指定子串算法: voiddelsubstring(HstringS,HstringT) {inti=0,j,k; while(i {for(j=i,k=0;k if(S.ch[j]! =T.ch[k]) break; if(k>=T.length) {while(j {S.ch[j-T.length]=S.ch[j]; j++;} S.length=S.length-T.length;} else i++; } } 3.判断串是否为回文算法: inttringcomp(HstringS,HstringT) {char*p,*q; p=S.ch;q=S.ch+S.length-1; while(p {p++;q--;} if(p>=q)return1; return0; } 课后习题解答 基础知识题 1.简述下列每对术语的区别: 空串和空白串;串常量和串变量;主串和子串;静态分配的顺序串和动态分配的顺序串5、目标考核模式串;有效位移和无效位移。 【答案】略 2.假设有如下的串说明chars1[30]="Stocktom,CA",s2="March5,1999",s3[30],*p; (1)在执行下列语句后,P的值是什么? p=strchr(s1,'t');p=str(s3,'9');p=strchr(s2,'6'); (2)在执行下列语句后,S3的值是什么? strcpy(s3,s1);strcat(s3,",");strcat(s3,s2); (3)调用函数strcmp(s1,s2)的返回值是什么? (4)调用函数strcmp(&s1[5],"tom")的返回值是什么? (5)调用函数strlen(strcat(s1,s2))的返回值是什么? 【答案】 (1)p的值依次为字符t在串s1中的位置,字符9在串s3中的位置,字符6在串s2中的位置。 (2)执行语句strcpy(s3,s1);后,S3的值是: "Stocktom,CA" 执行语句strcat(s3,",");后,S3的值是: "Stocktom,CA," 执行语句strcat(s3,s2);后,S3的值是: "Stocktom,CA,March5,1999" (3)调用函数strcmp(s1,s2)的返回值是: 大于0; (4)调用函数strcmp(&s1[5],"tom")的返回值是: 大于0 (5)调用函数strlen(strcat(s1,s2))的返回值是: s1和s2联接后的串长度: 23 3.T[0..n-1]="abaabaabcaabaa",P[0..m-1]="aab"。 当用模式串P匹配目标串,请给出所有的有效位移。 算法NaiveStrMatch(T,P)返回的位移是哪一个位移。 【答案】所有的有效位移依次为: 2,5,9;算法NaiveStrMatch(T,P)返回的位移是: 2 算法设计题 4.利用C的库函数strlen,strcpy和strcat写一个算法voidstrinsert(char*S,char*T,inti),将串T插入到串S的第i个位置上。 若i大于S的长度,则插入不执行。 【答案】 #include"string.h" #definmaxsize256 voidstrinsert(char*S,char*T,inti) {intslen; charsbuf[maxsize]; slen=strlen(S); if(i<0||i>slen) printf("invalidparai\n"); else {strcpy(sbuf1,S,i); strcat(sbuf1,T); strcpy(sbuf2,S+i); strcat(sbuf1,sbuf2); strcpy(S,sbuf1); printf("stringS: %s",S); } } 5.利用C的库函数strlen,strcpy和strcat写一个算法voidstrdelete(char*S,inti,intm),删去串S中从第i个字符开始的连续m个字符。 若i≥strlen(S),则没有字符被删除,若i+m≥strlen(S),。 则将串S中从第i个字符开始直到末尾的字符删去。 【答案】 #definmaxsize256 #include"string.h" voidstrdelete(char*S,inti,intm) {intslen; charsbuf1[maxsize],sbuf2[maxsize]; slen=strle
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构第04章 数据结构 04
![提示](https://static.bdocx.com/images/bang_tan.gif)