串
串的定义
串(string)(或字符串)是由零个或多个字符组成的有限序列。
串的抽象数据类型定义:
ADT String {
数据对象:
数据关系:
基本操作:
StrAssign(&T, chars); // 赋值
StrCopy(&T, S); // 复制
StrEmpty(S); // 判空
StrLength(S); // 获取长度
ClearString(&S); // 清空
Concat(&T, S1, S2); // 拼接
SubString(&Sub, S, pos, len); // 用Sub返回串S的第pos个字符起长度为len的子串
Index(S, T, pos); // 子串T第一次出现的位置,从pos开始查找
Replace(&S, T, V); // 用V替换T
StrInsert(&S, pos, T); // 在第pos个字符前插入串T
StrDelete(&S, pos, len);// 删除第pos个字符起长度为len的子串
DestroyString(&S); // 销毁串S
}ADT String
定位函数Index(S,T,pos)
int Index(String S, String T, int pos)
{
if(pos > 0) {
n = StrLength(S); m = StrLength(T); i = pos;
while(i <= n-m+1) {
SubString(sub, S, i, m);
if(StrCompare(sub, T) != 0) ++i;
else return i;
}
}
return 0;
}
串的表示和实现
定长顺序存储表示
#define MAXSTRLEN 255
typedef unsigned char SString[MAXSTRLEN + 1];
堆分配存储表示
以一组地址连续的存储单元存放串字符序列,但它们的存储空间是在程序执行过程中动态分配而得。
typedef struct {
char *ch;
int length;
}HString;
插入
Status StrInsert(HString &S, int pos, HString T) {
if(pos < 1 || pos > S.length + 1) return ERROR;
if(T.length) {
if(!(S.ch = (char *)realloc(S.ch, (S.length + T.length)*sizeof(char))))
exit(OVERFLOW);
for(i=S.length-1; i>=pos-1; --i)
S.ch[i+T.length] = S.ch[i];
S.ch[pos-1..pos+T.length-2] = T.ch[0..T.length-1];
s.length += T.length;
}
return OK;
}
算法基本操作
typedef struct {
char *ch;
int length;
}HString;
Status StrAssign(HString &T, char *chars) {
if(T.ch) free(T.ch);
for(i=0, c=chars; c; ++i, ++c);
if(!i) { T.ch = NULL; T.length = 0;}
else {
if(!(T.ch = (char *)malloc(i*sizeof(char))))
exit(OVERFLOW);
T.ch[0..i-1 = chars[0..i-1];
T.length = i;
}
return OK;
}
串操作应用举例
文本编辑
文本编辑程序中设立页指针、行指针和字符指针,分别指示当前操作的页、行和字符。
建立词索引表
宜采用链表结构的线性表
#define MaxBookNum 1000 //假定只对1000本书建索引表
#define MaxKeyNum 2500 // 索引表的最大容量
#define MaxLineLen 500 // 书目串的最大长度
#define MaxWordNum 10 // 词表的最大容量
typedef struct {
char *item[]; // 字符串的数组
int last; // 词表的长度
}WordListType; // 词表类型(顺序表)
typedef int ElemType; // 定义链表的数据元素类型为整型(书号类型)
typedef struct {
HString key; // 关键词
LinkList bnolist; // 存放书号索引的链表
}IdxTermType; // 索引项类型
typedef struct {
IdxTermType item[MaxKeyNum + 1];
int last;
}IdxListType; // 索引表类型(有序表)
// 主要变量
char *buf; // 书目串缓冲区
WordListType wdlist; // 词表
// 基本操作
void InitIdxList(IdxListType &idxlist); // 初始化操作,置索引表idxlist为空表,且在idxlist.item[0]设一空串
void GetLine(FILE f); // 从文件f读入一个书目信息到书目串缓冲区buf
void ExtractKeyWord(ElemType &bno); // 从buf中提取书名关键词到词表wdlist, 书号存入bno
Status InsIdxList(IdxListType &idxlist, ElemType bno); // 将书号为bno的书名关键词按词典顺序插入索引表idxlist
void PutText(FILE g, IdxListType idxlist); // 将生成的索引表idxlist输出到文件g
void main() {
if(f = openf("BookInfo.txt", "r"))
if(g = openf("BookIdx.txt", "w")) {
InitIdxList(idxlist); // 初始化索引表idxlist为空表
while(!feof(f)) {
GetLine(f); // 从文件f读入一个书目信息到buf
ExtractKeyWord(BookNo); // 从buf提取关键词到词表,书号存入BookNo
InsIdxList(idxlist, BookNo); // 将书号为BookNo的关键词插入索引表
}
PutText(g, idxlist); // 将生成的索引表idxlist输出到文件g
}
}
// 索引表插入算法
Status InsIdxList(IdxListType &idxlist, int bno) {
for(i=0; i<wdlist.last; ++i) {
GetWord(i, wd); j = Locate(idxlist, wd, b);
if(!b) InsertNewKey(idxlist, j, wd); // 插入新的索引项
if(!InsertBook(idxlist, j, bno)) return OVERFLOW; // 插入书号索引
}
return OK;
}
void GetWord(int i, HString &wd) {
p = *(wdlist.item + i); // 取词表中第i个字符串
StrAssign(wd, p); // 生成关键字字符串
}
int Locate(IdxListType &idxList, HString wd, Boolean &b) {
for(i = idxlist.last-1; (m=StrCompare(idxlist.item[i].key, wd)) >0; --i);
if(m==0) { b=TRUE; return i;} // 找到
else { b = FALSE; return i+1; }
}
void InsertNewKey(int i, StrType wd) {
for(j=idxlist.last-1; j>=i; --j) // 后移索引项
idxlist.item[j+1] = idxlist.item[j];
// 插入新的索引项
StrCopy(idxlist.item[i].key, wd); // 串赋值
InitList(idxlist.item[i].bnolist); // 初始化书号索引表为空表
++idxlist.last;
}
Status InsertBook(IdxListType &idxlist, int i, int bno) {
if(!MakeNode(p, bno)) return ERROR; // 分配失败
Appand(idxlist.item[i].bnolist, p); // 插入新的书号索引
return OK;
}