数据结构 第四章 串.docx

上传人:b****1 文档编号:10256520 上传时间:2023-05-24 格式:DOCX 页数:13 大小:23.50KB
下载 相关 举报
数据结构 第四章 串.docx_第1页
第1页 / 共13页
数据结构 第四章 串.docx_第2页
第2页 / 共13页
数据结构 第四章 串.docx_第3页
第3页 / 共13页
数据结构 第四章 串.docx_第4页
第4页 / 共13页
数据结构 第四章 串.docx_第5页
第5页 / 共13页
数据结构 第四章 串.docx_第6页
第6页 / 共13页
数据结构 第四章 串.docx_第7页
第7页 / 共13页
数据结构 第四章 串.docx_第8页
第8页 / 共13页
数据结构 第四章 串.docx_第9页
第9页 / 共13页
数据结构 第四章 串.docx_第10页
第10页 / 共13页
数据结构 第四章 串.docx_第11页
第11页 / 共13页
数据结构 第四章 串.docx_第12页
第12页 / 共13页
数据结构 第四章 串.docx_第13页
第13页 / 共13页
亲,该文档总共13页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

数据结构 第四章 串.docx

《数据结构 第四章 串.docx》由会员分享,可在线阅读,更多相关《数据结构 第四章 串.docx(13页珍藏版)》请在冰点文库上搜索。

数据结构 第四章 串.docx

数据结构第四章串

第四章 串

串又称字符串,是一种特殊的线性表,它的每个元素仅由一个字符组成。

计算机上非数值处理的对象基本上是字符串数据。

在较早的程序设计语言中,字符串仅作为输入和输出的常量出现。

随着计算机应用的发展,在越来越多的程序设计语言中,字符串也可作为一种变量类型出现,并产生了一系列字符串的操作。

在信息检索系统、文字编辑程序、自然语言翻译系统等等应用中,都是以字符串数据作为处理对象的。

本章将讨论串的存储结构和基本操作。

4.1串的基本概念

4.1.1串的自然语言定义

串(string)(或字符串)是由零个或多个字符组成的有限序列,一般记为:

S="a1a2……an"(n≥0)

其中,S是串名,用双引号括起来的字符串序列是串的值;ai(1≤i≤n)可以是字母、数字或其他字符;串中字符的个数n称为串的长度。

长度为0的串称为空串。

需要注意的是,串值必须用一对双引号括起来,但双引号本身不属于串,它的作用只是为了避免与变量名或数的常量混淆。

如"tempt"是个串,tempt则是变量名;"23"是串,而23则是一个常量.

串中任意个连续的字符组成的子序列称为该串的子串,如:

串S="Thisisastring",其中"This"是一个子串,"string"也是一个子串。

求子串在串中的起始位置称为子串定位或模式匹配。

  例如,设A,B,C为如下三个串:

A="data",B="structure",C="datastructure",则它们的长度分别是4,9,14,A和B都是C的子串,A在C中的位置是1,而B在C中的位置是6。

下面注意区别空格串与空串的概念。

在各种应用中,空格常常是串的字符集合中的一个元素,因而可以出现在其他字符中间。

由一个或多个空格组成的串称为空格串,也就是说空格串中只有空格字符,空格串的长度不为零。

而空串的长度为零,通常用

来表示,在C程序中表示成"",它是任意串的子串。

为了清楚起见,以后我们用“└┙”表示空格字符。

若称两个串是相等的,一定是这两个串的值相等。

即:

只有当两个串的长度相等,并且各个对应位置上的字符都相等时,才认为这两个串相等。

串的逻辑结构和线性表极为相似,区别仅在于串的数据对象约束为字符集。

但串的基本操作和线性表却有很大的差别。

在线性表的基本操作中,大多以“单个元素”作为操作对象,例如在线性表中查找某个元素、取某个元素、在某个位置上插入一个元素和删除一个元素等;而在串的基本操作中,通常以“串的整体”作为操作对象,例如在串中查找某个子串、求取一个子串、在串的某个位置上插入一个子串以及删除一个子串等。

4.1.2串的ADT定义

ADT String{

数据对象:

D={ai|ai∈ElemSet,i=1,2,…,n,n≥1}

数据关系:

R={|ai-1,ai∈D,i=2,3,…,n}

基本操作:

StrCopy(T,S):

拷贝函数,将串S复制到串T;

StrEmpty(S):

判断空串,若S为空串,则返回1,否则返回0;

StrCompare(S,T):

比较两个串的大小。

若S>T,则返回值为正整数;若S=T,则返回值为0;若S

StrLength(S):

求长度函数,返回S中元素的个数;

ClearString(S):

清空串,将S置空串;

Concat(S,T1,T2):

联接函数,用S返回T1和T2联接而成的新串,如:

T1="xyz",T2="abc",则Concat(S,T1,T2)="xyzabc",注意Concat(S,T1,T2)≠Concat(S,T2,T1);

SubString(S,pos,len):

求子串函数,取从S中第pos个字符起,长度为len的字符序列,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1;

Index(S,T):

定位函数,若在主串S中存在和T相等的子串,则函数值返回在S中出现的第一个和T相等的子串在S中的位置,否则返回0。

注意T不能是空串;

Replace(S,T,V):

置换操作。

操作结果是以串V替换所有在串S中出现的和串T相等的不重叠的子串。

如:

设S="bbabbabba",T="ab",V="a",则Replace(S,T,V)的结果是S="bbababa";

StrInsert(S,pos,T):

插入操作,当1≤pos≤StrLength(S)+1时,在串S的第pos个字符之前插入串T;

StrDelete(S,pos,len):

删除操作,当1≤pos≤StrLength(S)-len+1时,从串S中删去第pos字符起长度为len的子串。

}ADTList

4.2串的顺序存储结构及其运算

4.2.1串的顺序定长存储结构

  用一组地址连续的存储单元存储串的字符序列,构成串的顺序存储,简称为顺序串。

可以用一个特定的、不会在串中出现的字符作为串的终止符,放在串的最后,表示串的结束。

在C语言中用字符'\0'作为串的终止符。

若不设终止符,可用一个整型变量记录串的长度,顺序串的数据类型描述如下:

#defineMAXSIZE100

typedefstruct

{charch[MAXSIZE];

intlength;

}SqString;

例如:

S="abc└┙def└┙ghi└┙jkl",串长为15,本章规定字符串都从ch[1]单元开始存放,ch[0]单元不用,串的顺序存储结构如图4-1所示。

 

图4-1串S的顺序存储结构示意图

4.2.2顺序串的基本操作

1.联接操作

在操作时需考虑可能出现的三种情况,假设定义了两个指针变量SqString*t1,*t2:

①当t1->length+t2->length

②当t1->lengthlength+t2->length>MAXSIZE,则两串联接得到的S串是串t1和串t2的一个子串的联接,串t2的后面部分被截断,S串的长度等于MAXSIZE;

③当t1->length=MAXSIZE,则两串联接得到的S串实际上只是串t1的拷贝,串t2全部被截断,S串的长度等MAXSIZE。

voidConcat(SqStringS,SqStringt1,SqStringt2)

{//由串t1和串t2联接而成的新串存放在串S中。

若长度超过规定的长度,则截断

inti,n=MAXSIZE-1;

if(t1->length+t2->length<=n){//第一种情况

for(i=1;i<=t1->length;i++)S->ch[i]=t1->ch[i];

for(i=1;i<=t2->length;i++)S->ch[i+t1->length]=t2->ch[i];

S->length=t1->length+t2->length;

}

elseif(t1->length

for(i=1;i<=t1->length;i++)S->ch[i]=t1->ch[i];

for(i=1;i+t2->length<=n;i++)S->ch[i+t1->length]=t2->ch[i];

S->length=n;

}

else{//第三种情况

for(i=1;i<=n;i++)S->ch[i]=t1->ch[i];

S->length=n;

}

}//Concat

2.求子串操作

SqString*SubString(SqString*S,intpos,intlen)

{//返回S串中的第pos个字符起长度为len的子串

SqString*sub;

inti;

if(pos<1||pos>S->length||len<0||len>S->length-pos+1){

printf(“参数错误”);

sub->length=0;

}

else{

for(i=1;i<=len;i++)sub->ch[i]=S->ch[pos+i-1];

sub->length=len;

}

returnsub;

}//SubString

顺序串有一个缺点,就是串空间的大小都是静态的,这种定长的串空间难以适应插入、联接等操作。

在实际应用中常采用一种称为堆结构的动态存储结构,下面介绍堆分配存储结构的串。

4.3串的堆分配存储结构及其运算

4.3.1串的堆分配存储结构

  串的堆分配存储结构仍以一组地址连续的存储单元存放串的字符序列,但其存储空间是在算法执行过程中动态分配得到的。

利用函数malloc()为每一个新产生的串分配一块实际需要的存储空间,若分配成功,则返回一个指针,指向串的起始地址。

串的堆分配存储结构描述如下:

typedefstruct

{char*ch;

intlength;

}HString;

4.3.2串的堆分配存储结构的基本操作

1.联接操作

voidConcat_h(HString*S,HString*t1,HString*t2)

{//将串t1和串t2联接而成的新串存入S中

inti;

S->ch=(char*)malloc((t1->length+t2->length)*sizeof(char));

for(i=1;i<=t1->length;i++)S->ch[i]=t1->ch[i];

for(i=1;i<=t2->length;i++)S->ch[i+t1->length]=t2->ch[i];

S->length=t1->length+t2->length;

}//Concat_h

2.求子串操作

HString*SubString_H(HString*S,intpos,intlen)

{//返回S串中的第pos个字符起长度为len的子串

HString*sub;

inti;

if(pos<1||pos>S->length||len<0||len>S->length-pos+1){

sub->ch=NULL;sub->length=0;

}

else{

sub->ch=(char*)malloc(len*sizeof(char));

for(i=1;i<=len;i++)sub->ch[i]=S->ch[i+pos-1];

sub->length=len;

}

returnsub;

}//SubString_H

4.4串的链接存储结构

和线性表类似,串也可采用链式方式存储串值。

由于串结构非常特殊,它结构中的每个数据元素都是一个字符,那么用链表存储串值时,存在一个“结点大小”的问题,即每个结点可以存放一个字符,也可以存放多个字符。

例如图4-2(a)是结点大小为4(即每个结点存放4个字符)的链表,图4-2(b)是结点大小为1的链表。

当结点大小大于1时,由于串长不一定是结点大小的整倍数,则链表中的最后一个结点不一定全被串值占满,此时通常补上“#”或其他的非串值字符。

 

(a)结点大小为4的链表

 

(b)结点大小为1的链表

图4-2串值的链表存储方式

串的链式数据类型中结点大小为1的结点描述如下:

typedefstructNode

{chardata;

structNode*next;

}LinkString;

串值的链式存储结构对某些串操作,如联接操作等有一定方便之处,但总的说来不如另外两种存储结构灵活,它占用存储量大且操作复杂。

串值在链式存储结构时串操作的实现和线性表在链式存储结构中的操作类似,故在此不作详细讨论。

4.5应用举例及分析

例4_1在串的顺序定长存储结构上实现子串的定位Index(S,T)操作。

子串的定位操作通常称作串的模式匹配(其中T称为模式),是各种串处理系统中最重要的操作之一。

下面算法是利用判等、求子串等操作来实现函数Index(S,T)的。

算法的思路是:

在主串S中从i=1开始取一长度和串T长度相等的子串与串T进行比较,若相等,则函数返回i;否则i增加1,从i=2开始取一长度和串T长度相等的子串与串T进行比较,重复上述的过程,直至确定在串S中取不到和串T长度相等的子串为止,函数返回0。

或在S中取到一个和串T相等的子串,函数返回i。

操作过程如4-3图所示:

 

图4-3串的定位操作示意图

intIndex(SqString*S,SqString*t)

{inti,n,m,flag;

n=S->length;

m=t->length;

flag=0;

i=1;

while(i<=n-m+1&&(!

flag)){

if(StrCompare(SubString(S,i,m),t))flag=1;

elsei++;

}

if(flag)returni;

elsereturn0;

}//Index

如不调用其他的串操作函数,算法如下:

intIndex_2(SqString*S,SqString*t)

{inti=1,j=1;

while(i<=S->length&&j<=t->length)

if(S->ch[i]==t->ch[i]){

i++;j++;

}

else{

i=i-j+2;

j=1;

}

if(j>t->length)returni-t->length;

elsereturn0;

}//Index_2

例4_2一个文本串可用事先给定的字母映射表加密。

例如,设字母映射表为:

abcdefghijklmnopqrstuvwxyz

ngzqtcobmuhelkpdawxfyivrsj

则字符串"encrypt"被加密为"tkzwsdf"。

试写一算法将输入的文本串加密后输出,以及另一算法解密后输出。

Charkey[26]={‘n’,‘g’,‘z’,‘q’,‘t’,‘c’,‘o’,‘b’,‘m’,‘u’,‘h’,‘e’,‘l’,‘k’,‘p’,‘d’,‘a’,‘w’,‘x’,‘f’,‘y’,‘i’,‘v’,‘r’,‘s’,‘j’,}

voidEncrypt(char*S)

{inti=0,k=0;

while(S[i]!

=NULL){

k=(int)(S[i]!

=NULL)

S[i]=key[k];

i++;

}

}//Encrypt

voidDecrypt(char*S)

{inti=0;k;

while(S[i]!

=NULL){

k=0;

while(S[i]!

=key[k])k++;

S[i]='a’+k;

i++;

}

}//Decrypt

4.6上机实验

4.6.1实验目的

⑴掌握字符串的基本操作。

⑵加深对字符串的理解,逐步培养解决实际问题的编程能力。

4.6.2实验内容

⑴采用顺序结构存储串,编写一个函数SubStr(str1,str2),用于判定str2是否为str1的子串。

设str1="a0a1…am",str2="b0b1…bn"。

从str1中找与b0匹配的字符ai,若ai=b0,则判定ai+1=b1,…ai+n=bn;若都相等,则结果是子串,否则继续比较ai之后的字符。

⑵编写一个函数,实现在两个已知字符串中找出所有非空最长公共子串的长度和最长公共子串的个数。

设两个字符串的首结点指针分别为str1和str2,它们的长度分别记为length1和length2。

设有length1>length2,则它们最长的公共子串长度不超过length2。

 

本章小结

⑴串又称为字符串,是一类特殊的线性表,它的每个元素仅由一个字符组成。

⑵一个串可以包含若干个子串。

子串是指由串中任意个连续字符组成的子序列,串的最大子串是它自身,最小子串是空串(长度为零的串)。

对串的操作,往往针对一组连续的字符进行。

⑶空串与空格串是不相同的,空串的长度为0,空格串的长度是指包含的空格个数。

⑷两个串相等的充分必要条件是它们的长度相等且对应位置上的字符相同。

⑸本章讨论字符串的基本概念,存储方法和串的基本操作。

 

练习题

一、选择题

1.串是由0个或多个字符组成的有限序列,它是一种特殊的线性表,其特殊性表现在(  )。

A.可以采用顺序和链式存储B.每一个元素都只有一个前驱和后继

C.删除和插入操作只能在一端进行D.每一个数据元素都是一个字符

2.空格串是指(  )。

A.一个字符也没有的字符串B.由若干个任意字符组成的字符串

C.由零个字符组成的字符串D.只含空格字符的字符串

3.设有两个串p和q,求q在p中首次出现的位置的运算称作(  )。

A.插入子串B.连接子串C.模式匹配D.替换子串

4.在字符串的替换操作中,设替换前的字符串为str="ABCDEFG",把从第2个字符开始的连续3个字符替换成"abcd",则替换后str="(  )"。

A.AabcEFGB.AabcBCDEFGC.AabcdEFGD.AabcdBCDEFG

5.下列对串的存储结构叙述不正确的是(  )。

A.串可以采用顺序存储也可以采用链式存储

B.顺序串可以采用静态数组来存储也可以采用动态数组来存储

C.串在存储时需附加存储一个结束标志

D.串中的每一个数据元素都是一个字符,故串只能采用字符数组来存储

二、填空题

1.串的两种最基本的存储方式是    和    。

2.两个串相等的充分必要要件是                    。

3.空串是              ,其长度等于  。

4.空格串是             ,其长度等于         。

5.设S="I└┙AM└┙A└┙TEACHER",其长度是  。

6.设S1="GOOD",S2="└┙",S3="BYE!

",则S1、S2和S3连接后的结果是  。

7.已知substr(s,i,len)函数的功能是返回串s中第i个字符开始长度为len的子串,strlen(s)函数的功能是返回串s的长度。

若s="ABCDEFGHIJK",t="ABC",则执行strlen(t)后的返回值为  ,执行substr(s,strlen(t),strlen(t))后的返回值为()。

8.已知s1="I’mastudent",s2="student",s3="teacher",则StrLength(s1)的结果是  ;Concat(s2,s3)的结果是;StrDelete(s1,4,10)的结果是  。

三、问答题

1.串是由字符组成的有限序列,长度为1个串与单个字符是否等同?

2.串有哪几种存储结构?

3.串是由字符构成的特殊线性表、串的操作与线性表的操作主要不同之处是什么?

4.分别写出串的静态数组存储结构和串的动态数组存储结构的定义。

5.简述空格串的定义及其长度。

四、算法及程序设计题

1.若X和Y是两个单链表存储的串,试设计一个算法,找出X中第一个不在Y中出现的字符来。

2.在链串中,设计一个算法把最先出现的子串"ab"改为"xyz"。

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

当前位置:首页 > 工程科技 > 兵器核科学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2