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

`我们生活在一个字符串的世界里。位字符串构成了整数和浮点数,数字符串构成了电话号码,字母字符串构成了单词,长字符串可以形成网页,更长的字符串则形成书。在遗传学家的数据库和人的细胞里,存在着由字母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 500

char 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的大部分实现都采用平衡树。

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

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值