一、 串的基本概念
串(或字符串),是由零个或多个字符组成的有穷序列。
含零个字符的串称为空串,用Ф表示。串中所含字符的个数称为该串的长度(或串长)。
通常将一个串表示成“a1a2…an”的形式。其中最外边的双引号本身不是串的内容,它们是串的标志,以便将串与标识符(如变量名等)加以区别。每个ai(1≤i≤n)代表一个字符。
当且仅当两个串的长度相等并且各个对应位置上的字符都相同时,这两个串才是相等的。
一个串中任意个连续字符组成的子序列(含空串)称为该串的子串。例如,“a”、“ab”、“abc”和“abcd”等都是“abcde”的子串(真子串是指不包含自身的所有子串)。
二、串的顺序存储及其基本操作实现
在顺序串中,串中的字符被依次存放在一组连续的存储单元里。一般来说,一个字节(8位)可以表示一个字符(即该字符的ASCII码)。
因此,一个内存单元可以存储多个字符。例如,一个32位的内存单元可以存储4个字符(即4个字符的ASCII码)。
串的顺序存储有两种方法:一种是每个单元只存一个字符,这称为非紧缩格式(其存储密度小);另一种是每个单元存放多个字符,这称为紧缩格式(其存储密度大)。
对于非紧缩格式的顺序串,其类型定义如下:
#define MaxSize 100
typedef struct
{ char data[MaxSize];
int length;
} SqString;
顺序串中实现串的基本运算如下:
(1)StrAssign(s,cstr)
将一个字符串常量赋给串s,即生成一个其值等于cstr的串s。
void StrAssign(SqString &s,char cstr[])//s为引用型参数
{ int i;
for (i=0;cstr[i]!='\0';i++)
s.data[i]=cstr[i];
s.length=i;
}
(2)StrCopy(s,t)
将串t复制给串s。
void StrCopy(SqString &s,SqString t)//s为引用型参数
{ int i;
for (i=0;i<t.length;i++)
s.data[i]=t.data[i];
s.length=t.length;
}
(3)StrEqual(s,t)
判串相等:若两个串s与t相等返回真(1);否则返回假(0)。
bool StrEqual(SqString s,SqString t)
{ bool same=true;
int i;
if (s.length!=t.length) //长度不相等时返回0
same=false;
else
for (i=0;i<s.length;i++)
if (s.data[i]!=t.data[i])
{ same=false;
break;
}
return same;
}
(4)StrLength(s)
求串长:返回串s中字符个数。
int StrLength(SqString s)
{
return s.length;
}
(5)Concat(s,t)
串连接:返回由两个串s和t连接在一起形成的新串。
SqString Concat(SqString s,SqString t)
{ SqString str;
int i;
str.length=s.length+t.length;
for (i=0;i<s.length;i++) //s.data[0..s.length-1]str
str.data[i]=s.data[i];
for (i=0;i<t.length;i++) //t.data[0..t.length-1]str
str.data[s.length+i]=t.data[i];
return str;
}
(6)SubStr(s,i,j)
求子串:返回串s中从第i(1≤i≤StrLength(s))个字符开始的、由连续j个字符组成的子串。参数不正确时返回一个空串。
SqString SubStr(SqString s,int i,int j)
{ SqString str;
int k;
str.length=0;
if (i<=0 || i>s.length || j<0 || i+j-1>s.length)
return str; //参数不正确时返回空串
for (k=i-1;k<i+j-1;k++) //s.data[i..i+j]str
str.data[k-i+1]=s.data[k];
str.length=j;
return str;
}
(7)InsStr(s1,i,s2)
将串s2插入到串s1的第i(1≤i≤StrLength(s)+1)个字符中,即将s2的第一个字符作为s1的第i个字符,并返回产生的新串。参数不正确时返回一个空串。
SqString InsStr(SqString s1,int i,SqString s2)
{ int j; SqString str;
str.length=0;
if (i<=0 || i>s1.length+1) //参数不正确时返回空串
return str;
for (j=0;j<i-1;j++) //将s1.data[0..i-2]str
str.data[j]=s1.data[j];
for (j=0;j<s2.length;j++) //s2.data[0..s2.length-1]str
str.data[i+j-1]=s2.data[j];
for (j=i-1;j<s1.length;j++) //s1.data[i-1..s1.length-1]str
str.data[s2.length+j]=s1.data[j];
str.length=s1.length+s2.length;
return str;
}
(8)DelStr(s,i,j)
从串s中删去第i(1≤i≤StrLength(s))个字符开始的长度为j的子串,并返回产生的新串。参数不正确时返回一个空串。
SqString DelStr(SqString s,int i,int j)
{ int k; SqString str;
str.length=0;
if (i<=0 || i>s.length || i+j>s.length+1) return str; //参数不正确时返回空串
for (k=0;k<i-1;k++) //s.data[0..i-2]str
str.data[k]=s.data[k];
for (k=i+j-1;k<s.length;k++) //s.data[i+j-1..s.length-1]str
str.data[k-j]=s.data[k];
str.length=s.length-j;
return str;
}
(9)RepStr(s,i,j,t)
在串s中,将第i(1≤i≤StrLength(s))个字符开始的j个字符构成的子串用串t替换,并返回产生的新串。参数不正确时返回一个空串。
SqString RepStr(SqString s,int i,int j,SqString t)
{ int k; SqString str; str.length=0;
if (i<=0 || i>s.length || i+j-1>s.length)
return str; //参数不正确时返回空串
for (k=0;k<i-1;k++) //s.data[0..i-2]str
str.data[k]=s.data[k];
for (k=0;k<t.length;k++) //t.data[0..t.length-1]str
str.data[i+k-1]=t.data[k];
for (k=i+j-1;k<s.length;k++) //s.data[i+j-1..s.length-1]str
str.data[t.length+k-j]=s.data[k];
str.length=s.length-j+t.length;
return str;
}
(10)DispStr(s)
输出串s的所有元素值。
void DispStr(SqString s)
{ int i;
if (s.length>0)
{ for (i=0;i<s.length;i++)
printf("%c",s.data[i]);
printf("\n");
}
}