1. 程式人生 > >PAT甲級 1078 Hashing (25 分)(二次方探查法)

PAT甲級 1078 Hashing (25 分)(二次方探查法)

1078 Hashing (25 分)

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.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive numbers: MSize (≤10​4​​) and N (≤MSize) which are the user-defined table size and the number of input numbers, respectively. Then N distinct positive integers are given in the next line. All the numbers in a line are separated by a space.

Output Specification:

For each test case, print the corresponding positions (index starts from 0) of the input numbers in one line. All the numbers in a line are separated by a space, and there must be no extra space at the end of the line. In case it is impossible to insert the number, print "-" instead.

Sample Input:

4 4
10 6 4 15

Sample Output:

0 1 4 -

題目大意:給出散列表長和要插入的元素,將這些元素按照讀入的順序插入散列表中,其中雜湊函式為h(key) = key % TSize,解決衝突採用只向正向增加的二次方探查法。如果題中給出的TSize不是素數,就取第一個比TSize大的素數作為TSize分析:先解決size是否為素數,不是素數就要重新賦值的問題然後根據二次方探查法:– 如果hashTable裡面key % size的下標對應的hashTable為false,說明這個下標沒有被使用過,直接輸出。否則step步長從1加到size-1,一次次嘗試是否能使index = (key + step * step) % size;所對應的位置沒有元素,如果都沒有找到就輸出“-”,否則就輸出這個找到的元素的位置~注意: 判斷是不是素數,高效的方法是對 2 到  根號n  的數求餘判斷。另外table的尺寸要是大於輸入的最小素數,而輸入範圍最大可以是10000,所以若用for迴圈找最小素數,迴圈上限最好是100000。

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;

int m,n;
vector<int> arr,flag;
bool isprime(int n){
	if(n<=1)
		return false;
	for(int i=2;i*i<=n;i++)
		if(n % i == 0)
			return false;
	return true;
}

void insert(int num){
	for(int j=0;j<n;j++){
		int key = (num+j*j)%m;
		if(flag[key] == 0){
			flag[key] = 1;
			printf("%d",key);
			return ;
		}
	}
	printf("-");
}

int main(){
	cin>>m>>n;
	while(!isprime(m))m++;
	
	arr.resize(n,0);
	for(int i=0;i<n;i++)
		cin>>arr[i];
	
	flag.resize(m,0);
	for(int i=0;i<n;i++){
		insert(arr[i]);
		if(i != n-1)
			printf(" ");
	}
	
	return 0;
}