二次探测法,只考虑正增量。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int Hash[10001];
int Msize,N;
int prime(int n){
int k=sqrt(n);
int flag=0;
if(n==0||n==1){
return 2;
}
if(n==2||n==3){
return n;
}
for(int i=2;i<=k;i++){
if(n%i==0){
flag=1;
break;
}
}
if(flag){
return prime(n+1);
}
else{
return n;
}
}
int main(){
int key,flag=1;
scanf("%d%d",&Msize,&N);
int size=prime(Msize);
for(int i=0;i<=size;i++){
Hash[i]=-1;
}
//memset(Hash,-1,sizeof(Hash));不对!!
cout<<Hash[0]<<endl;
for(int i=0;i<N;i++){
scanf("%d",&key);
int pos=key%size;
if(!flag){
printf(" ");
flag=1;
}
if(Hash[pos]==-1){
Hash[pos]=key;
printf("%d",pos);
flag=0;
}
else{
int n=1;
while((Hash[pos]!=-1)&&n<N){
pos=(key%size+n*n)%size;
n++;
}
if(n<N){
Hash[pos]=key;
printf("%d",pos);
flag=0;
}
else{
printf("-");
flag=0;
}
}
}
return 0;
}
还有一个之前的版本,应该是刚学过hash的时候做的,那时候还不懂c++和STL。。。
#include<stdio.h>
int Prime(int x);
int main(){
int M,N,t;
scanf("%d %d",&M,&N);
t=Prime(M);
int H[t],i,j,key;
int flag=1,n;
for(i=0;i<t;i++){
H[i]=-1;
}
// printf("%d",t);
for(i=0;i<N;i++){
scanf("%d",&key);
j=key%t;
if(!flag){
printf(" ");
flag=1;
}
if(H[j]==-1){
H[j]=key;
printf("%d",j);
flag=0;
}
else{
n=1;
while(H[j]!=-1&&n<N){
j=(key%t+n*n)%t;
++n;
}
if(n<N){
H[j]=key;
printf("%d",j);
flag=0;
}
else{
printf("-");
flag=0;
}
}
}
}
int Prime( int x )
{ int i;
int NotPrime = 0;
if( x==1||x==0 )
return 2;
if( x==2 || x==3 )
return x;
for( i=2; i*i<=x; i++ )
{
if( x%i==0 ){
NotPrime = 1;
break;
}
}
if( !NotPrime )
return x;
else
{
x++;
return Prime(x);
}
}