建立自己的散列表, 散列表中的节点包含指向单词的指针、单词出现的频率以及指向表中的下一个节点
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
//圣经中只有29131个单词, 采用传统的方法, 将大于29131的最小的质数作为散列表的大小
const int NHASH = 29989;
const int MULT = 31;
//用结构体来实现散列表
typedef struct node {
char *word;
int count;
node* next;
}*nodeptr;
nodeptr bin[NHASH];
//hash function 将每个字符串映射为小于NHASH的整数
unsigned int hash(char* p)
{
unsigned int h = 0;
for (; *p; ++p)
{
h = MULT * h + *p;
}
return h % NHASH;
}
//负责增加与输入单词相关联的计数器的值,如果以前没有这个数值,就会进行初始化
void Incword(char *s)
{
unsigned int h = ::hash(s);
nodeptr p = bin[h];
for (; p != NULL; p = p->next)
{
if (strcmp(p->word, s) == 0)
{
++p->count;
return;
}
}
p = (nodeptr)malloc(sizeof(node));
p->count = 1;
p->word = (char*)malloc(strlen(s) + 1);
strcpy(p->word, s);
p->next = bin[h];
bin[h] = p;
}
void Init()
{
for (int i = 0; i < NHASH; ++i)
{
bin[i] = NULL;
}
}
int main()
{
Init();
string s;
while (cin >> s)
{
char buf[32];
strcpy(buf, s.c_str());
Incword(buf);
}
for (int i = 0; i < NHASH; ++i)
{
for (nodeptr p = bin[i]; p != NULL; p = p->next)
{
cout << p->word << " shows up " << p->count << endl;
}
}
return 0;
}
使用标准库中的map将整数计数与每个字符串联系起来
#include <iostream>
#include <set>
#include <string>
#include <map>
using namespace std;
int main()
{
map<string, int> M;
map<string, int>::iterator j;
string t;
while (cin >> t)
M[t]++;
for (j = M.begin(); j != M.end(); ++j)
cout << j->first << " shows up " << j->second << endl;
return 0;
}