例题:
给你一堆英文单词(可能有4000000个。用普通查询铁定让你TLE)。找出出现次数最多的,输出这个单词,并输出出现的次数。
思路:
hash离散数据,进行查询即可。(转化为数字时)
1.首先将每个字符串转化为一个数字。
2.把离散后的结果存入hashnode[]数组中。(初始化头结点全部为空,且头结点不存内容,只是判断离散后是否有这个结果)
3.插入+查询操作
4.在插入过程中不断比较,找出最大的单词数目,并记录。(maxcount,ans[11])。若该结果出现过,则与结点内容想比较,相同则该结点单词数目加1。否则查找以此数字为离散结果的下一个结点(离散结果相同)。
没出现过:开辟新结点,插入到以此数字为离散结果的单链表中,单词数目设为1,字符串复制至结点中。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
#define MAX 20000
int maxcount = 0;
char ans[11];
struct Node
{
int num; //结点数目
char str[11]; //结点数组
Node *next; //下一个结点
};
Node hashnode[MAX];
void init() //初始化数组
{
for(int i = 0; i < MAX; ++i)
hashnode[i].next = NULL;
}
int separate(char str[]) //离散化
{
int len, sum;
len = strlen(str);
sum = 0;
for(int i = 0; i < len; ++i)
{
sum = (sum * 180 + (int)str[i]) % MAX; //离散函数(越散时间越快,空间占用越大)
}
return sum;
}
void search(char str[]) //查找+插入
{
int tmp;
tmp = separate(str);
Node *p, *q;
p = hashnode[tmp].next;
while(p != NULL) //离散结果出现,比较并计数
{
if(strcmp(str, p->str) == 0)
{
p->num++;
if(p->num > maxcount) //记录最大值
{
maxcount = p->num;
strcpy(ans, str);
}
return ;
}
p = p->next;
}
q = new Node; //没出现过,开辟新结点
q->next = hashnode[tmp].next;
hashnode[tmp].next = q;
q->num = 1;
strcpy(q->str, str);
}
int main()
{
int num;
char str[11];
init();
scanf("%d", &num);
while(num--)
{
scanf("%s", str);
search(str);
}
printf("%s %d\n", ans, maxcount);
return 0;
}