南邮 OJ 1523 Cuckoo Hashing

Cuckoo Hashing

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 54            测试通过 : 20 

比赛描述

One of the most fundamental data structure problems isthe dictionary problem: given a set of words you want to


be able to quickly determine if any given query string is
present in the dictionary or not. Hashing is a well-known
solution for the problem. The idea is to create a function
: Σ∗ → [0..n − 1] from all strings to the integer range
01,..,n − 1, i.e. you describe a fast deterministic program
which takes a string as input and outputs an integer between
0 and n− 1. Next you allocate an empty hash table of size
and for each word in D, you set T[h(w)] = w. Thus, given a query string q, you only
need to calculate h(q) and see if T[h(q)] equals q, to determine if is in the dictionary.
Seems simple enough, but aren’t we forgetting something? Of course, what if two words
in map to the same location in the table? This phenomenon, called collision, happens
fairly often (remember the Birthday paradox: in a class of 24 pupils there is more than
50% chance that two of them share birthday). On average you will only be able to put
roughly n-sized dictionaries into the table without getting collisions, quite poor space
usage!
A stronger variant is Cuckoo Hashing1. The idea is to use two hash functions hand
h2. Thus each string maps to two positions in the table. A query string is now handled
as follows: you compute both h1(q) and h2(q), and if T[h1(q)] = qor T[h2(q)] = q, you
conclude that is in D. The name “Cuckoo Hashing” stems from the process of creating
the table. Initially you have an empty table. You iterate over the words in D, and
insert them one by one. If T[h1(d)] is free, you set T[h1(d)] = d. Otherwise if T[h2(d)] is
free, you set T[h2(d)] = d. If both are occupied however, just like the cuckoo with other
birds’ eggs, you evict the word in T[h1(d)] and set T[h1(d)] = d. Next you put back
into the table in its alternative place (and if that entry was already occupied you evict
that word and move it to its alternative place, and so on). Of course, we may end up
in an infinite loop here, in which case we need to rebuild the table with other choices of
hash functions. The good news is that this will not happen with great probability even if
contains up to n/2 words!



输入

On the first line of input is a single positive integer 1 ≤ ≤ 50 specifying the number oftest cases to follow. Each test case begins with two positive integers 1 ≤ ≤ ≤ 10000on a line of itself, telling the number of words in the dictionary and the size of the hash table in the test case. Next follow lines of which the i:th describes the i:th word din the dictionary by two non-negative integers h1(di) and h2(di) less than giving
the two hash function values of the word di. The two values may be identical.

输出

For each test case there should be exactly one line of output either containing the string successful hashing” if it is possible to insert all words in the given order into the table, or the string “rehash necessary” if it is impossible.

样例输入

2
3 3
0 1
1 2
2 0
5 6
2 3
3 1
1 2
5 1
2 5

样例输出

successful hashing
rehash necessary

提示

undefined

题目来源

Nordic Collegiate Programming Contest 2007




#include<stdio.h>
#include<memory.h>
int a[10000][2];		//a[i][]:第i个元素的两个hash值
bool visited[10000];	//确定第i个元素摆放位置是否被访问标志
int table[10000];		//表中存放的值
int m,n;

bool place(int i){
	for(int j=0; j<2; j++){
		int k = a[i][j];
		if(!visited[k]){
			visited[k] = 1;
			if(table[k]==-1 || place(table[k])){	//现在的位置没放数据,或者可以让现在的数据移位
				table[k] = i;
				return 1;
			}
		}
	}
	return 0;
}

int main(){
	int t,i,j;
	scanf("%d",&t);
	while(t--){
		scanf("%d%d",&m,&n);
		memset(table,-1,sizeof(int)*n);				//用memset可以省时间,注意设置4个char的-1与1个int的-1效果相同,都是每位置一
		for(i=0; i<m; i++){
			scanf("%d%d",&a[i][0],&a[i][1]);
		}
		for(i=0; i<m; i++){
			memset(visited,0,sizeof(bool)*n);
			if(!place(i)){
				break;
			}
		}
		if(i<m){
			printf("rehash necessary\n");
		}else{
			printf("successful hashing\n");
		}
	}
}



你可能感兴趣的:(ACM,hashing,Cuckoo,南邮OJ)