41串.docx
《41串.docx》由会员分享,可在线阅读,更多相关《41串.docx(8页珍藏版)》请在冰豆网上搜索。
![41串.docx](https://file1.bdocx.com/fileroot1/2022-11/16/26a1911c-76fc-4783-a854-c7d35dbe45e6/26a1911c-76fc-4783-a854-c7d35dbe45e61.gif)
41串
第四章串
编辑软件(Edit、Word本质上是字符串处理)、
信息检索(字符串比较)
编译软件、语言翻译
第一节逻辑结构
一、定义
串是由字符组成的线性表。
抽象数据类型:
STRING=(D,S,P)
D={ai|ai∈CHARACTER(字符集),i=0,1,2,…,n-1}
S={|ai-1,ai∈D,i=1,2,…,n-1}
ASCII码串:
CHARACTER为ASCII码字符集。
位串:
CHARACTER={0,1}
几个概念:
(1)串的长度:
‘a0a1……an-1’的长度为n。
(2)空串:
长度为0。
’’
(3)子串:
串中任意个连续字符组成的子序列。
(4)串的位置
(4)串相等
二、基本运算
线性表
注重单个元素的操作
串
注重整体或部分整体的操作
基本操作子集
赋值StrAssign(&T,chars)
判断StrEmpty(S)
串比较StrCompare(S,T)
求长度StrLength(S)
联接Concat(&T,S1,S2)
取子串SubString(&Sub,S,pos,len)
子串定位Index(S,T,pos)
替换Replace(&S,T,V)
插入StrInsert(&S,pos,T)
删除StrDelete(&S,pos,len)
释放DestroyString(&S)
其它操作可在基本操作子集上实现:
(1)定位函数Index(S,T,pos)
//?
“串比较”、“求串长”和“求子串”3个基本操作
intIndex(StringS,StringT,intpos){
//T为非空串。
若主串S中第pos个字符之后存在与T相等的子串,则返回第一个这样的子串在S中的位置,否则返回0。
if(pos>0){
n=StrLength(S);m=StrLength(T);i=pos;
while(i<=n-m+1){
SubString(sub,S,i,m);
if(StrCompare(sub,T)!
=0)
i++;
elsereturni;//如果存在,返回位序
}//while
}//if
return0;//S中不存在与T相等的子串,返回0
}//Index
(2)串替换Replace(S,T,V)
voidreplace(String&S,StringT,StringV){
n=StrLength(S);m=StrLength(T);pos=1;
StrAssign(news,NullStr);//news字符串,中间变量
i=1;
while(pos<=n-m+1&&i){
i=Index(S,T,pos);
if(i!
=0){//找到子串
SubString(sub,S,pos,i-pos);
Concat(news,news,sub);Concat(news,news,V);
pos=i+m;//?
}//if
}//while
SubString(sub,S,pos,n-pos+1);//剩余串
Concat(S,news,sub);
}
第二节存储结构
一、定长顺序存储
用一组地址连续的存储单元存储串值。
#defineMAXSTRLEN255
typedefcharSString[MAXSTRLEN+1];
组织形式:
①String[0]存放串的长度(PASCAL语言)。
②以结束标记符号’\0’,标记串的终结(C语言)。
优点:
访问子串方便
缺点:
串长限定,空间大小不灵活,插入、删除费时。
statusSubString(SString&Sub,SStringS,intpos,intlen){
//用Sub返回串S的第pos个字符起长度为len的子串
//1≤pos≤StrLength(S),0≤len≤Strlength(S)-pos+1
if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1)
returnERROR;
Sub[1..len]=S[pos..pos+len-1];//如何理解?
细化
Sub[0]=len;
returnOK;
}
for(i=1;i<=len;i++)
Sub[i]=S[pos+i-1];
Concat(SString&T,SStringS1,SStringS2){
//用T返回由S1和S2联接而成的新串,若未截断,则返回TRUE,否则FALSE。
}
三种可能:
基本操作:
字符序列的复制
Sub[1..len]=S[pos..pos+len-1];
T[1..S1[0]]=S1[1..S1[0]];
T[S1[0]+1..S1[0]+S2[0]]=S2[1..S2[0]];
T[0]=S1[0]+S2[0]
课后完成基本操作
二、堆分配存储
特点:
仍以一组地址连续的存储单元存放串值字符序列,但他们的存储空间是在程序执行过程中动态分配而得,分配一块实际串长所需的存储空间。
即动态数组
C语言动态分配函数:
malloc()、free(),管理自由存储区:
“堆”
typedefstruct{
char*ch;
intlength;//串长度
}Hstring;
区别:
typedefcharSString[maxstrlen+1];
基本操作:
StatusStrAssign(Hstring&T,char*chars)
{
inti;char*c;
for(i=0,c=chars;c!
=’\0’;++i,++c);//获取字符串chars的长度
if(!
i){T.ch=NULL;T.length=0;}//空串
else
{
T.ch=(char*)malloc(i*sizeof(char));
If(!
T.ch)printf(“OVERFLOW!
”);
for(k=0;k
T.length=i;
}
returnOK;
}
调用:
chara[50];
HstringT;
scanf(“%s”,a);
strAssign(&T,a);
StatusConcat(HString&T,Hstrings1,HStrings2)
{
intk;
T.ch=(char*)malloc((s1.length+s2.length)*sizeof(char));
If(!
T.ch)printf(“OVERFLOW!
”);
T.length=s1.length+s2.length;
For(k=0;kT.ch[k]=s1.ch[k];
For(k=0,kreturnOK;
}
比较定长顺序存储的contact(P73)
三、链式存储(块链存储)
如何设置结点的大小?
一个结点存储1个字符:
非紧缩格式。
一个结点存储多个字符:
紧缩格式。
#defineCHUNKSIZE80
typedefstructChunk//块结构
{charch[CHUNKSIZE];
structChunk*next;
}CHUNK;
typedefstruct
{CHUNK*head,*tail;
intcurlen;//串的长度
}LString;
优点:
在联接操作有一定方便之处。
总体而言,不灵活,占用存储量大且操作复杂。
例如,如何在紧缩格式的链串中插入、删除?
作业:
1、利用字符串的定长顺序存储结构实现如下操作:
char*Concat(chars1[],chars2[])
2、利用字符串的堆分配存储实现如下操作:
statusStrCopy(Hstring&T,HStringS){}
//将串S的值复制到串T中。