目录
1.串的抽象类型定义
1.1 串的逻辑结构和线性结构和线性表很相似,区别仅仅在于串的数据对象越少为字符集。但是串的基本操作和线性表却有很大差别。 串通常以“串的整体”为操作对象,可以查找、求取、插入和删除字串。
1.2串的抽象类型定义
ADT String {
数据对象:D={ ai | ai∈ CharacterSet,i=1 ,2 ,…, n,n≥ 0 }
结构关系:R1={< ai-1,ai >| ai-1,ai ∈ D ,i=2 ,…, n }
基本操作:
StrAssign( &T , chars )
初始条件:chars是字符串常量。
操作结果:生成一个其值等于chars的串T。
StrCopy( &T , S )
初始条件:串S存在。
操作结果:由串S复制得到串T。
StrEmpty( S )
初始条件:串S存在。
操作结果:若S是空串,返回true,否则返回false。
StrCompare(S,T)
初始条件:串S和T存在。
操作结果:若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0;
StrLength(S)
初始条件:串S存在。
操作结果:返回S的元素个数,称为串的长度。
ClearString (&S)
初始条件:串S存在。
操作结果:将S清为空串。
Concat ( &T, S1, S2)
初始条件:串S1和S2存在。
操作结果:用T返回S1和S2连接在一起的串。
SubString( &Sub,S,pos,len)
初始条件:串S存在,1<=pos<=StrLength(S)且0<=len<=StrLength(S)-pos+1。//(注意:pos位置是指第pos位,所以是从第一位开始算)
操作结果:用Sub返回串S的第pos个字符起长度为len的子串。
Index(S,T,pos)
初始条件:串S和T存在,且T为非空串,1<=pos<=StrLength(S)。
操作结果:若主串S存在和串T值相同的子串,则返回它在主串中第pos个字符后第一次出现的位置,否则函数值为0。
Replace(&S, T,V)
初始条件:串S、T和V存在,T为非空串。
操作结果:用V替换主串S中出现的所有与T相等的不重复的子串。
StrInsert(&S, pos, T)
初始条件:串S和T存在,1<=pos<=StrLength(S)+1。
操作结果:在串S的第pos个字符之前插入串T。
StrDelete(&S, pos, len)
初始条件:串S存在,1<=pos<=StrLength(S)-len+1。
操作结果:从串S中删除第pos个字符起长度为len的子串。
DestroyString(&S)
初始条件:串S存在。
操作结果:串S被销毁。
}ADT String
2.串的存储结构
2.1顺序存储
2.1.1串的定长顺序存储结构
#define MAXLEN 255 //串的最大长度
typedef struct{
char ch[MAXLEN+1]; //储存串的一维数组
int length; //串的当前长度
}SString;
注意:采用从下标为1的数组分量开始存储,下标为0的分量闲置不用
2.1.2串的堆式顺序存储结构
typedef struct{
char *ch; //若是非空串,则按串长分配存储区,否则ch为NULL;
int length; //串的当前长度
}HString;
2.2链式存储
(不常用)
在链式存储中,结点的大小的选择会直接影响着串的处理效率。
结点大小问题:每个结点可以存放一个字符也可以存放多个字符;当结点大小大于1时,由于串长不一定是结点大小的整数倍,则链表中的最后一个结点不一定全被串值填满,此时通常用“#”或者其他的非串值字符(通常,“#”不属于串的字符集,是一个特殊符号)。
//串存储结构为块链结构
#define CHUNKSIZE 80 //可以自定义的块大小
typedef struct Chunk //结点大小
{
char ch[CHUNKSIZE];
struct Chunk * next;
}Chunk;
typedef struct
{
Chunk * head,*tail; //串的头和尾指针
int length; //串的当前长度
}LString;