PAT 解题报告 1078. Hashing (25)

1078. Hashing题目描述:

The task of this problem is simple: insert a sequence of distinct positive integers into a hash table, and output the positions of the input numbers. The hash function is defined to be “H(key) = key % TSize” where TSize is the maximum size of the hash table. Quadratic probing (with positive increments only) is used to solve the collisions.

Note that the table size is better to be prime. If the maximum size given by the user is not prime, you must re-define the table size to be the smallest prime number which is larger than the size given by the user.

模拟open addressing的哈希表的插入, 让输出每个元素插入到哈希表中的位置, 解决哈希表的冲突的时候采用二次探测的方法.

1078. Hashing算法分析:

考点无非是需找质数, 还有模拟哈希表的二次探测的方法. 使用这个函数h(k, i) = (k + i * i) % table_size去寻找元素应该插入的位置, 遍历一遍以后找不到就说明无法插入, 找大于给定的那个table size的质数的时候可以采用素数表或者使用平方根检测都可以. AC代码如下:

#include <cstdio>
#include <vector>
#include <algorithm>
#include <cassert>

int h(int k, int i, int tSize) {
	return (k % tSize + (i * i) ) % tSize;
}

bool test(int val, int i) {
	return (val != i) && !(val % i);
}

int plist[10010];
int pcount = 0;
bool prime(int n) {
	int i;
	if( test(n, 2) || test(n, 3) || test(n, 5) || test(n, 7) )
		return false;

	for(i = 0; plist[i] * plist[i] <= n; ++i) {
		if(!(n % plist[i]))
			return false;
	}
	return n > 1;
}

int initPrime(int tsize) {
	if(tsize <= 2)
		return 2;

	plist[pcount++] = 2;
	for(int i = 3; i < 10020; i += 2) {
		if(prime(i)) {
			plist[pcount++] = i;
			if(i >= tsize)
				return i;
		}
	}
	return tsize;
}

int redefineSize(int tablesize) {
	return initPrime(tablesize);
}

int hInsert(std::vector<int> & table, int k, int tSize) {
	assert(k > 0);
	int i = 0;
	int j = 0;
	for(int i = 0; i < tSize; ++i) {
		j = h(k, i, tSize);
		if(0 == table[j]) {
			table[j] = k;
			return j;
		}
	}
	return -1;
}

int main() {
	pcount = 0;
	int MSize, N;
	scanf("%d %d", &MSize, &N);

	MSize = redefineSize(MSize);

	std::vector<int> indexes(N, -1);	 
	std::vector<int> table(MSize, 0);	 
	
	int num;  
	for(int i = 0; i < N; ++i) {
		scanf("%d", &num);
		indexes[i] = hInsert(table, num, MSize);
	}

	for(int i = 0; i < N; ++i) {
		if(0 == i) {
			if(-1 == indexes[i])
				printf("-");
			else
				printf("%d", indexes[i]);
		}
		else {
			if(-1 == indexes[i])
				printf(" -");
			else
				printf(" %d", indexes[i]);
		}
	}
	printf("\n");
	return 0;
}

1078. Hashing注意点:

(1) 1不是质数……
(2) 第一个大于10000的质数是10007

Written on May 2, 2014