数据结构作业——寻人启事(字符串哈希)

寻人启事

Description

才来到福州大学的你很想要知道你几位失散多年的朋友是否也来到了福州 大学,于是你黑进了学校的学籍管理系统,但无奈里面的记录太多了,想通过一 条条比对查找他们的信息过于麻烦, 现在你决定写一个程序帮助你加快查找速度。

Input

第一行输入包括 n、m 两个数字,表示学籍系统里共 n(n<=1000000)条记 录,m(m<=1000 且 m<=n)个你想要寻找的朋友。接下来 n 行每行一个长度不 超过 5 的名字代表这个人的名字,在接下来 m 行每行一个长度不超过 5 的名字 代表想要寻找的人的名字。

Output

输出一个整数 k,代表学校中朋友的数量。

Sample Input

3 2
Tom
Alice
Jack
Jack
Ted

Sample Output

1

HINT

系统里的名字没有重复。
待查询的名字没有重复。

思路

简单的hash题,冲突利用分离链表法解决,并且用邻接表代替链表。主要在于hash函数的构造,一开始构造了个简单的hash函数,导致冲突过多,速度很慢,后来换了Horner法则构造,冲突极大的减少。

 AC代码
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int mod = 999983;
const int maxn = 1000005;
char str[maxn][10];
int tot = 0,head[mod+5],next[maxn];

int IndexHash(char *key)   //Hormer法则
{
	int hashval = 0;
	while (*key != '\0')	hashval = (hashval<<5) + *key++;
	return hashval % mod; 
}

void addnode(int hashval)
{
	next[tot] = head[hashval];
	head[hashval] = tot++;
}

int main()
{
	//freopen("data.txt","r",stdin);
	//freopen("2.txt","w",stdout);
	int n,m,i,cnt = 0;
	char tmp[10];
	memset(str,0,sizeof(str));
	memset(head,-1,sizeof(head));
	scanf("%d%d",&n,&m);
	for (i = 0;i < n;i++)
	{
		scanf("%s",str[i]);
		int hashval = IndexHash(str[i]); 
		addnode(hashval);
	}
	while (m--)
	{
		scanf("%s",tmp);
		int hashval = IndexHash(tmp);
		for (i = head[hashval];i != -1;i = next[i])
		{
			if (strcmp(tmp,str[i]) == 0)	cnt++; 
		}
	}
	printf("%d\n",cnt);
	return 0;
}

对拍程序

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<map>
#include<string>
using namespace std; 
const int maxn = 1000000;

int main()
{
	freopen("data.txt","w",stdout);
	srand(time(NULL));
	map<string,int>mp1,mp2;
	map<string,int>::iterator it;
	int n = maxn,m = rand()%n;
	printf("%d %d\n",n,m);
	for (int i = 0;i < n;)
	{
		string str;
		int len = rand()%5 + 1;
		while (len--)	str += rand()%58 + 'A';
		it = mp1.find(str);
		if (it == mp1.end())	cout << str << endl,i++;
		mp1[str] = 1;
	}
	for (int i = 0;i < m;)
	{
		string str;
		int len = rand()%5 + 1;
		while (len--)	str += rand()%58 + 'A';
		it = mp2.find(str);
		if (it == mp2.end())	cout << str << endl,i++;
		mp2[str] = 1;
	}
	return 0;
} 

  

posted @ 2016-10-28 12:20  zxzhang  阅读(340)  评论(0)    收藏  举报