《编程珠玑》代码之路21:设计一个比C++库函数快一个数量级的《圣经》单词统计功能

给出这么一个问题,统计《圣经》出现的所有单词以及其出现次数,单词定义为两个空格之间的词语,当然开头结尾这种自然也是单词。

容易想到的是用C++库函数的map,但这其实并不是最优的选择,根据实际情况选择最优的数据结构,比直接调库,要好玩的多。

怎么办呢,《圣经》中有29131个不同的单词,我们可以做一个散列,大小用最接近单词数量的质数,乘数定义为31,这也是散列技术比较传统的办法。

如果冲突的话,就把冲突的词放在一个链表上。下面给出的代码,会比简单调用库函数快十倍不止:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

struct Node{
	char *word;
	int count;
	Node *next;
}node;

const int NHASH = 29989;
const int MULT = 31;
Node *bin[NHASH + 10];

unsigned int hash(char *p);
void incWord(char *str);

int main(){

	freopen("in.txt", "r", stdin);
	for (int i = 0; i < NHASH; ++i){
		bin[i] = NULL;
	}

	char str[10000];
	while (cin >> str){
		incWord(str);
	}

	for (int i = 0; i < NHASH; ++i){
		for (Node *p = bin[i]; p != NULL; p = p->next){
			cout << p->word << "  " << p->count << endl;
		}
	}


	return 0;
}

unsigned int hash(char *p){

	unsigned int h = 0;
	for (; *p; ++p){
		h = MULT * h + *p;
	}
	return h % NHASH;
}

void incWord(char *str){
	unsigned int h = hash(str);

	Node *p = NULL;
	for (p = bin[h]; p != NULL; p = p->next){
		if (strcmp(str, p->word) == 0){
			(p->count)++;
			return;
		}
	}

	p = new Node();
	p->count = 1;
	p->word = new char(strlen(str) + 1);
	strcpy(p->word, str);
	p->next = bin[h];
	bin[h] = p;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值