一. 串类型的定义
字符串是n(n>=0)个字符的有限序列,记作: S=“C1C2C3...Cn”
其中:S是串名字;
“C1C2C3…Cn” 是串值;
Ci 是串中字符;
n 是串的长度;
n=0 称为空串;
由一个或多个空白符组成的串称为空白串;
串中任意个连续字符组成的子序列称为该串的子串;
包含子串的串相应地称为主串;
通常将子串在主串中首次出现时,该子串首字符对应的主串中的序号,定义为子串在主串中的位置。
例如,设 A = “This is a string” , B = “is” 则B是A的子串,A为主串。B在A中出现了两次,首次出现所对应的主串的位置是2(从0开始)。因此,称B在A中的位置为2.
空串是任意串的子串,任意串是其自身的子串。二. 串的表示和实现
除C语言提供的字符串库函数外,可以自定义字符串。
适用于自定义字符串数据类型的有三种存储表示:
定长顺序存储表示
;堆分配存储表示
;块链存储表示
。
定长顺序存储表示
顺序串:使用静态分配的字符数组存储字符串中的字符序列。
字符数组的长度预先用MAXSTRLEN确定,一旦空间存满,不能扩充。
有两种实现定长顺序存储表示:
字符串存放于字符数组的0 ~ MAXSTRLEN-1单元,另外用整数length记录串中实际存放的字符个数。
字符串存放于字符数组的1 ~ MAXSTRLEN-1单元,用0号单元记录串中实际存放的字符个数。
定长存储表示的定义如下:#define MAXSTRLEN 256 //顺序串的预设长度 typedef struct{ //顺序串的定义 char SString[MAXSTRLEN] //存储字符数组 int length; //串中实际字符个数 }SqString;
堆分配存储表示
- 堆式串:字符数组的存储空间是通过malloc()函数动态分配的。
- 串的最大空间数MAXSTRLEN和串中实际字符个数length保存在串的定义中。
- 可以根据需要,随时改变字符数组的大小。
- 堆分配存储表示的定义如下:
#define MAXSTRLEN 256 //顺序串的预设长度 typedef struct{ char *ch; //存储字符数组 int maxSize; //串数组的最大长度 int length; //串的当前长度 }HString;
块链存储表示
- 使用单链表作为字符串的存储表示,此即字符串的链接存储表示。
- 链表的每个结点可以存储1个字符,称其块的大小为1,也可以存储n个字符,称其块的大小为n。
- 定义存储密度为:
存储密度越高,存储利用率越高。
块链存储表示一般带头结点,设置头,尾指针。
- 块链存储表示的定义如下:
#define blockSize 4 //由使用者定义的结点大小 typedef struct bloak{ char ch[blockSize]; struct block *next; //头结点 }Chunk; typedef struct{ Chunk *first, *last; //链表的头指针和尾指针 int length; //串的当前长度 }LString;
串的相关算法(堆存储部分操作的实现)
初始化空串算法
void initString(Hstring &S) { S.ch = (char *)malloc(MAXSTRLEN*sizeof(char)); //分配字符数组空间 if(S.ch == NULL) exit(1); //判断分配是否成功 S.ch[0] = '\0'; //置空串 S.maxSize = MAXSTRLEN; //置串的最大字符数 S.length = 0; //实际字符数置0 }
提取子串算法
代码实现:
HString subString(HString &s, int pos, int len) { HString tmp; //创建子串空间 tmp.ch = (char *)malloc(MAXSTRLEN*sizeof(char)); tmp.maxSize = MAXSTRLEN; if(pos<0 || len<0 || pos+len-1 >= s.maxSize) { //参数不合理,返回空串 tmp.length = 0; tmp.ch[0] = '\0'; } else { if(pos+len-1 >= s.length) len = s.length-pos; for(int i=0, j=pos; i<len; i++, j++) tmp.ch[i] = s.ch[i]; //复制子串的字符 tmp.length = len; tmp.ch[len] = '\0'; } return tmp; //返回复制的子串 }
串的连接算法
void concat(HeapString &s, Heapstring &t) { if(s.length + t.length <= s.maxSize) { //原空间可容纳连接后的串 for(int i=0; i<t.n; i++) s.ch[s.length+i] = t.ch[i]; //串t复制到串s后 s.length = s.length + t.length; s.ch[s.length]= '\0'; } else //原空间容不下连接后的串 { char *tmp = s.ch; s.maxSize = s.length + t.length; s.ch = (char *)malloc((s.maxSize+1)*sizeof(char)); strcpy(s.ch, tmp); //复制原串s数组 strcat(s.ch, t.ch); //连接串t数组 s.length = s.length + t.length; free(tmp); } }