数据结构之定长顺序存储表示
一、前言
1、串又称为字符串是由零个或者多个字符组成的有限序列
2、串相等:需要满足串的长度相同,且各个对应位置的字符都相等
3、串值必须用一对单引号括起来,但单引号本身不属于串(其作用是避免与变量名或者数的常量混淆而已)
4、串的逻辑结构和线性表极为相似,区别仅在于串的数据对象约束为字符集,而线性表的数据对象为单个元素。然而,串的基本操作和线性表有很大差别
5、串类型的最小操作子集又5个,分别是串赋值StrAssign、串比较StrCompare、求串长StrLength、串连接Concat、求子串
6、串的表示和实现有三种方式:定长顺序存储表示、堆分配存储表示、串的块链存储表示
二、串的定长顺序存储表示
1、用一组地址连续的固定长度的存储区存储字符序列,超出固定长度的串值被“截断”
2、该存储方式实现串基本操作的代码如下
// 串的定长顺序存储表示.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#define MAXSTRLEN 255
typedef unsigned char SString[MAXSTRLEN+1];//0号单元存放串的长度
/*初始化赋值*/
void StrAssign(SString &Str,char *cs)
{
int i=0;
while(*cs!='\0')
{
i++;
Str[i]=*cs;
cs++;
}
Str[0]=i;
}
/*串联接*/
void Concat(SString &T,SString S1,SString S2)
{
int s1Len=(int)S1[0];//将char类型强制转换为int类型
int s2Len=(int)S2[0];
if (s1Len+s2Len<=MAXSTRLEN)//未截断
{
T[0]=s1Len+s2Len;
for (int i=1;i<=s1Len;i++)
{
T[i]=S1[i];
}
for (int i=s1Len+1;i<=s1Len+s2Len;i++)
{
T[i]=S2[i-s1Len];
}
}
else if(s1Len<MAXSTRLEN)//截断S2
{
T[0]=s1Len+s2Len;
for (int i=1;i<=s1Len;i++)
{
T[i]=S1[i];
}
for (int i=s1Len+1;i<=MAXSTRLEN;i++)
{
T[i]=S2[i];
}
}
else//截段(仅取S1)
{
T[0]=MAXSTRLEN;
for (int i=1;i<=MAXSTRLEN;i++)
{
T[i]=S1[i];
}
}
}
/*求子串,获取串S中从第pos个位置之后,长度为len的子串*/
bool SubString(SString &Sub,SString S,int pos,int len)
{
if (pos<1||pos>(int)S[0]||len<0||len>(int)S[0]-pos+1)
{
return false;
}
Sub[0]=len;
for (int i=pos;i<=pos+len-1;i++)
{
Sub[i-pos+1]=S[i];
}
return true;
}
/*求串长*/
int StrLength(SString str)
{
return (int)str[0];
}
/*串复制*/
void StrCope(SString &T,SString str)
{
int strLen=StrLength(str);
T[0]=strLen;
for (int i=1;i<=strLen;i++)
{
T[i]=str[i];
}
}
/*串比较*/
int StrCompare(SString S,SString T)
{
int LenMin=StrLength(S)>=StrLength(T)?StrLength(S):StrLength(T);
for (int i=1;i<=LenMin;i++)
{
if (S[i]>T[i])
{
return 1;
}
else if (S[i]<T[i])
{
return -1;
}
}
if (StrLength(S)==StrLength(T))
{
return 0;
}
else
{
return StrLength(S)>StrLength(T)?1:-1;
}
}
/*打印字符串*/
void printfString(SString str)
{
int len=(int)str[0];
for (int i=1;i<=len;i++)
{
printf("%c",str[i]);
}
printf("\n");
}
3、基本操作测试代码如下
//程序运行
int _tmain(int argc, _TCHAR* argv[])
{
char *cs1="sunhaoyu";
SString S1;
StrAssign(S1,cs1);//串赋值
printfString(S1);
char *cs2=" is Mekeater";
SString S2;
StrAssign(S2,cs2);
printfString(S2);
//串连接
SString T;
Concat(T,S1,S2);
printfString(T);
//求子串
SString S3;
if (SubString(S3,T,4,3))
{
printfString(S3);
}
SString S4;
StrAssign(S4,"mynameismekeater");
printfString(S4);
//求串长
printf("上串的长度为 %d \n",StrLength(S4));
//串复制
SString C;
StrCope(C,S4);
printfString(C);
//串比较
SString S5;
StrAssign(S5,"mynameissunhaoyu");
printfString(S5);
int com=StrCompare(S4,S5);
if (com==0)
{
printf("S4=S5\n");
}
else if (com<0)
{
printf("S4<S5\n");
}
else
{
printf("S4>S5\n");
}
system("pause");
return 0;
}
4、运行结果如下
5、利用以上基本操作求从第pos个位置起,S子串中等于T的位置
/*利用以上基本操作求从第pos个位置起,S子串中等于T的位置*/
int index(SString S,SString T,int pos)
{
if (pos>0)
{
int n=StrLength(S);
int m=StrLength(T);
int i=pos;
SString sub;
while(i<n-m+1)
{
SubString(sub,S,i,m);
if (StrCompare(sub,T)!=0)
{
i++;
}
else
{
return i;
}
}
}
return -1;//S中不存在与T相等的子串
}
6、代码测试Index函数
int _tmain(int argc, _TCHAR* argv[])
{
SString S;
StrAssign(S,"sunhaoyu");
printfString(S);
SString T;
StrAssign(T,"hao");
printf("%d \n",index(S,T,1));
system("pause");
return 0;
}