编程珠玑(2)第十五章学习笔记

来源:互联网 发布:vs2017 js 智能感应 编辑:程序博客网 时间:2024/06/05 22:57

`我们生活在一个字符串的世界里。位字符串构成了整数和浮点数,数字符串构成了电话号码,字母字符串构成了单词,长字符串可以形成网页,更长的字符串则形成书。在遗传学家的数据库和人的细胞里,存在着由字母A、C、G和T表示的极长的字符串。

 

我们的第一个问题是:为文档中包含的单词生成一个列表。我们的第一个C++程序用到了标准模板库中的sets和strings。主要思想就是用set的insert函数直接插入即可。而set只能保存单词,却无法统计每个单词出现的次数。为了统计每个单词出现的次数,我们可以使用map这一数据结构。当然,为了节省时间,我们也可以自己建立散列表。

 

第二个问题是:给定一个文本文件作为输入,查找其中最长的重复子字符串。

有一个很简单的办法,暴力匹配所有字符串,但时间复杂度是O(n^2),无法令人满意。

还有一个办法,利用“后缀数组”。“后缀数组”是一个字符指针数组。下面是具体实现代码:

#include<stdio.h>#include<stdlib.h>#include<string.h>#define MAXN 500char c[MAXN], *a[MAXN];int pstrcmp(const void *a, const void *b)  //字符串数组qsort的比较函数{return strcmp(*(char**)a, *(char**)b);}int comlen(char *p, char *q){int i;i = 0;while(*p && *p++==*q++){i++;}return i;}int main(){char ch;int i, n;int maxlen, temp, maxi;n = 0;while((ch=getchar())!='\n'){ //在字符串输入的过程中建立后缀数组a[n] = &c[n];c[n++] = ch;}c[n] = NULL;qsort(a, n, sizeof(char*), pstrcmp); //对后缀数组排序maxlen = 0;maxi = 0;for(i=0; i<n-1; i++){temp = comlen(a[i], a[i+1]);if(temp > maxlen){maxlen = temp;maxi = i;}}printf("%.*s\n", maxlen, a[maxi]);return 0;}


原理:

字符串的数据结构。

散列。这一结构的平均速度很快,且易于实现。

平衡树。这些结构在最坏的情况下也有较好的性能,C++标准模板库的set和map的大部分实现都采用平衡树。

后缀数组。初始化指向文本中每个字符(或每个单词)的指针数组,对其排序就得到一个后缀数组。然后可以遍历该数组以查找接近的字符串,也可以使用二分搜索查找单词或短语。

这是本书的最后一章,看完之后有一些启发,但总觉得自己还有很多问题没弄明白,需要再接再砺啊!

原创粉丝点击