今天我们来讲一个很重要的数据成员—串
串的概念及基本定义
串是由零个或多个字符组成的有限序列。为了表示字符串的开始与结束,一般用双引号表示。长度就是字符数(注意:空格也算作是字符。长度为零的字符串称作是空串。
两个字符的相等是指这两个字符串中的任意位置的对应字符相等。字符串相等与这两个字符串的名字无关。
串的表示与实现
串的数组方式,有时也叫定长顺序的存储方式,和线性表的顺序存储结构类似。是用一组地址连续的存储单元存储串值中的字符序列。在这方式中,按照预定义的大小,为每一个串变量分配一个固定长度的存储区,一般用下标为零的数组分量来存放串的实际长度。
串的创建
typedef int Status;
Status CreateString(ElemType *S)
{
for(int i = 1;i < MAXSIZE;i++)
{
cin>>S[i];
}
S[0] = MAXSIZE;
return OK;
}
串的遍历
Status Traverse(ElemType *S)
{
if(!S)
return ERROR;
for(int i = 1;i <= S[0];i++)
{
printf("%c",S[i]);
}
return OK;
}
下面我们介绍一种重要的功能,即串的联结,分三种情况讨论:
1.S1[0]+S2[0]<=MAXSiZE
此时得到的串是正确的结果,包含原S1和S2的全部
2.S1[0]<MAXSIZE且S1[0]+S2[0]>MAXSIZE
则将串S2的一部分截断,生成的新串包含原来S1的全部和S2的一个子串
3.S1[0]=MAXSIZE
,则得到的新串和串S1相等,S2被全部截去。
具体算法如下:
Status Concat(ElemType *S1,ElemType *S2,ElemType *S)
{
if(S1[0] == 0||S2[0] == 0)
return ERROR;
if(S[0]>S1[0]+S2[0])
{
for(int i = 1;i <= S1[0];i++)
{
S[i] = S1[i];
}
for(int i = 1;i <= S2[0];i++)
{
S[i+S1[0]] = S2[i];
}
S[0] = S1[0]+S2[0];
}
else if(S[0]<S1[0]+S2[0]) //第三种情况与第二种合并
{
for(int i = 1;i <= S1[0];i++)
{
S[i] = S1[i];
}
for(int i = 1;i <=(S2[0]+S1[0])-S[0];i++)
{
S[i+S1[0]] = S2[i];
}
S[0]=10;
}
return OK;
}
串的堆存储结构
串的赋值
Status StringAssgin(Hstring &S,char *a) //a为用户输入的数字
{
S.length = strlen(a);
S.chars = (char *)malloc(S.length * sizeof(char));
if(!S.chars||!a)
{
return ERROR;
}
int i=0;
while(a[i] != '\0')
{
S.chars[i] = a[i];
i++;
}
return OK;
}
比较串的大小
Status Compare(Hstring &S1,Hstring &S2)
{
int i =0;
if(S1.length > S2.length) //S1大
return OK;
else if(S1.length < S2.length) //S2大
return ERROR;
else if(S1.length == S2.length)
{
while(S1.chars[i] != '\0')
{
if(S1.chars[i] > S2.chars[i])
return OK;
else if(S1.chars[i] < S2.chars[i])
return ERROR;
i++;
}
return 2; //二者相等
}
}
求子串
Status SubString(Hstring &Sub,Hstring &S,int pos,int len)
{
Sub.length = len;
Sub.chars = (char *)malloc(Sub.length * sizeof(char));
if(!S.chars)
return ERROR;
if(pos + len > S.length)
return ERROR;
for(int i = 0;i <= len;i++)
{
Sub.chars[i] = S.chars[i+pos];
}
return OK;
}
参考书籍:数据结构第二版