块链串 |
如果一个结点大小为 4 ,链域大小为 2 ,根据**存储密度=串值占用的存储位/实际为串分配存储位,故该字符串的存储密度为 2 /3 。**显然,串的存储密度越小,运算处理就越方便,但存储占用的量较大。应根据具体情况来确定使用串的何种存储结构。
- 结点大小等于 1 :当 BLOCK_SIZE 等于 1 时,每个结点存放 1 个字符,结构同线性链表,存
储结构可定义如下,插入、删除的处理方法和线性链表一样,参见本章典型题解部分串的链式
模式匹配,算法处理简单,但存储密度较低。 - 结点大于 1 :当 BLOCK_SIZE 大于 1 时,每个结点存放多个字符,当最后一个结点未存满
时,不足处可用特定字符(如#)补齐。虽然存储密度相对结点大小等于 1 的存储方法来说,存储
密度较高,但此时插入、删除的处理方法比较复杂,需要考虑结点的分拆和合并。
块链串的结构 |
#define BLOCK_SIZE 4 /*每结点存放字符个数 4*/
typedef struct Block
{
char ch[BLOCK_SIZE];
struct Block *next;
} Block;
typedef struct
{
Block *head;
Block *tail;
int len;
} BLString;
串的应用举例:简单的行编辑器 |
可将文本看成为一个大的字符串,文本编辑就相当对字符串的处理。文本编辑程序用于源程序的输入和修改,公文书信、报刊和书籍的编辑排版等。常用的文本编辑程序有Edit,WPS,Word 等。文本编辑的实质是修改字符数据的形式和格式,虽然各个文本编辑程序的功能不同,但基本操作是一样的,都包括串的查找、插入和删除等。
为了编辑方便,可以用分页符和换行符将文本分为若干页,每页有若干行。可以把文本当作一个字符串,称为文本串,页是文本串的子串,行是页的子串。这里采用堆存储结构来存储文本,同时设立页指针、行指针和字符指针,分别指向当前操作的页、行和字符,同时建立页表和行表存储每一页、每一行的起始位置和长度。
- 假设有如下 Pascal 源程序:
FUNC max(x,y:integer):integer;
VAR z:integer;
BEGIN
IF x>y THEN z:=x;
ELSE z:=y;
RETURN(z);
END;
该程序输入内存后放到一个堆中,如图 4.3 所示。其中↙为换行符。表 4-1 和表 4-2 分别
为下图所示文本串的页表和行表。
由表 4 -1 、表 4 -2 可以看出,当在某行内插入字符时,就要修改行表中该行的长度,若该行的长度超出了分配给它的存储空间,则要重新给它分配存储空间,同时修改它的起始位置和长度。如果要插入或删除一行,就要进行行表的插入和删除,当行的插入和删除涉及页的变化是时要对页表进行修改。
典型题例 |
要求编写一个用带头结点的单链表实现串的模式匹配算法,每个结点存放一个字符(结
点大小为 1 )。借助于前面的结点大小为 1 定义链串类型 LKString。
【问题分析】该算法类同顺序串的简单模式匹配,实现匹配过程需考虑链表的特征(从头
比较的技术,指针保留的技术)。
【算法思想】
①初始化:主串从start开始,模式串从头开始
②两串逐位比较:当主串模式串均未遍历完时,对应字符作比较
若相等:主串模式串的当前比较位置均后移
若不等:主串从开始比较位置的下一个开始,模式串从头开始
③判别:若匹配成功返回起始位置指针,若不成功,返回NULL
【算法描述】
Link *StrIndex(LKString *s, LKString *t)
/* 求模式串 t 在主串 s 中第一次出现的位置指针 */
{
Link *sp, *tp, *start;
if (t->len == 0)
return s->head->next; /* 空串是任意串的子串 */
start = s->head->next; /* 记录主串的起始比较位置 */
sp = start; /* 主串从 start 开始 */
tp = t->head->next; /* 模式串从第一个结点开始 */
while (sp != NULL && tp != NULL)
{
if (sp->ch == tp->ch) /* 若当前对应字符相同,则继续比较 */
{
sp = sp->next;
tp = tp->next;
}
else /* 发现失配字符,则返回到主串当前起始位置的下一个结点继续比较*/
{
start = start->next; /* 更新主串的起始位置 */
sp = start;
tp = t->head->next; /* 模式串从第一个结点重新开始 */
}
}
if (tp == NULL)
return start; /* 匹配成功,返回主串当前起始位置指针 */
else
return NULL; /* 匹配不成功,返回空指针 */
}