串操作应用举例

Published: by Creative Commons Licence

文本编辑

文本编辑程序是一个面向用户的系统服务程序,广泛用于源程序的输入和修改,甚至用于报刊和书籍的编辑排版以及办公室的公文书信的起草和润色。文本编辑器的实质是修改字符数据的形式或格式。虽然各种文本编辑程序的功能强弱不同,但是其基本操作是一致的,一般都包括串的查找插入删除等基本操作。

为了编辑的方便,用户可以利用换页符和换行符把文本划分为若干页,每页有若干行(当然也可不分页而把文件直接划分为若干行)。

我们可以把文本看成是一个字符串,称为文本串。是文本串的子串又是子串

比如这段源程序:

main(){
  float a,b,max;
  scanf("%f,%f",&a,&b);
  if(a>b) max=a;
  else max=b;
}

我们可以把此程序看成是一个文本串。输入到内存后如下:

文本格式示例

为了管理文本串的页和行,再进入文本编辑的时候,编辑程序先为文本串建立相应的页表和行表,即建立各子串的存储映像

页表的每一项给出了页号和该页的起始行号。而行表的每一项则指示每一行的行号、起始地址和该行子串的长度。

下面是上面文本串的行表:

行号 起始地址 长度
100 201 8
101 209 17
102 226 24
103 250 17
104 267 15
105 282 2

文本编辑程序中的基本操作

文本编辑程序中设立页指针、行指针和字符指针,分布指示当前操作的页、行和字符。

  • 如果在某行内插入或删除若干字符,则要修改行表中该行的长度。
  • 若该行的长度超出了分配给它的存储空间,则要为该行重新分配存储空间,同时还要修改该行的起始位置。
  • 如果要插入或删除一行,就要涉及行表的插入或删除。
  • 若被删除的行是所在页的起始行,则还要修改页表中相应页的起始行号(修改为下一行的行号)
  • 为了查找方便,行表是按行号递增顺序存储的,因此,对行表进行的插入或删除操作需移动操作位置以后的全部表项。(页表的维护与行表类似)
  • 由于访问是以页表和行表作为索引的,所以在作行和页的删除操作时,可以只对行表和页表作相应的修改,而不必删除所涉及的字符,这可减少不少时间。(空间换时间)

建立词索引表

信息检索是计算机应用的重要领域之一。由于信息检索的主要操作是在大量的存放在磁盘上的信息中查询一个特定的信息,为了提高查询效率,一个重要的问题是建立一个好的磁盘系统。

图书馆书目检索系统中有三张索引表i,分别可书名、作者名和分类号编排。在实际系统中,按书名检索并不方便,因为很多内容相似的书籍其书名不一定吸纳共同。因此较好的方法是建立“书名关键词搜索”。

下面讨论如何从书目文件生成书名关键字的有序此表。

重复下列操作直至文件结束:
1. 从书目文件中读入一个书目串
2. 从书目串中提取所有关键词插入词表
3. 对词表中的每一个关键词,在索引表中进行查找并作相应的插入操作

如何识别书名串中分离出的单词是否是关键词: 顺序扫描书名串,首先分离单词,然后查找常用词表(在英文书名中的"常用词"指的是诸如"an","a","of","the"等),若不和表中任一词相等,则为关键词,插入临时存放关键词的词表中。

索引表中查询关键词可能出现的两种情况:一是索引表上已有关键词的索引项,只要在该项中插入书号索引;二是需要在索引表中插入此关键词的索引项,插入应按字典有序原则进行。

插入操作(操作三)具体实现之设定数据结构:

词表为线性表。只存放一本书的书名中若干关键词,其数量有限,则采用顺序存储结构即可,其中每个词是一个字符串。

索引表为有序表,虽是动态生成,在生成过程中需频繁进行插入操作,但考虑索引表主要为查找用,为了提高查找效率(使用折半查找),宜采用顺序存储结构; 表中每个索引项包含两个内容:其一是关键词,因索引表为常驻结构,则应考虑节省存储,采用堆分配存储表示的串类型;其二是书号索引,由于书号索引是在索引表的生成过程中逐个插入,且不同关键词的书号索引个数不等,甚至可能相差很多,则宜采用链表结构的线性表

串的堆分配存储表示: 定长顺序存储结构和堆分配存储结构都是顺序存储结构,它们的主要区别是前者的串长是固定的,后者的串长是动态 串的定长顺序存储结构的缺点是限定了串的长度,若超出长度则约定截断 堆分配存储表示解决上面的问题,它动态分配串值得存储空间 串值共享的存储空间称之为堆,它由C语言的动态分配函数mallocfree管理