PAT甲题题解-1078. Hashing (25)-hash散列

二次方探测解决冲突
一开始理解错了,难怪一直WA。
先寻找key%TSize的index处,如果冲突,那么依此寻找
(key+j*j)%TSize的位置,j=1~TSize-1
如果都没有空位,则输出'-'

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
#include <cmath>
using namespace std;
const int maxn=10200; //之前设置的是10005,然后比10000大的第一个素数是10007
int isprime[maxn];
int prime[maxn];
int cnt=0;
int hashing[maxn]; //hash表
/*
素数筛选法,筛选出素数,在存储
然后用二分查找,用来查找比MSize大的最小的素数
*/
void init(){
    for(int i=0;i<maxn;i++)
        isprime[i]=1;
    isprime[1]=0;
    for(int i=2;i<maxn;i++){
        if(isprime[i]){
            for(int j=i*2;j<maxn;j+=i)
                isprime[j]=0;
        }
    }
    for(int i=2;i<maxn;i++){
        if(isprime[i]){
            prime[cnt++]=i;
//printf("%d\n",i);
        }
    }
}

/*
从素数中找出比给定的MSize大的最小素数
*/
int binarySearch(int val){
    int l=0,r=cnt-1,mid;
    while(l<r-1){
        mid=(l+r)>>1;
        if(val<=prime[mid])
            r=mid;
        else
            l=mid;
    }
    return prime[r];
}
int main()
{
    int m,n,TSize;
    init();
    scanf("%d %d",&m,&n);
    if(m==1)
        m=2; //如果m=1,则二分查找出来的是3,所以先要处理下
    if(!isprime[m]){
        TSize=binarySearch(m);
    }
    else
        TSize=m;

//printf("%d\n",TSize);
    int a[maxn];
    memset(hashing,0,sizeof(hashing));
    int pos,key;
    for(int i=0;i<n;i++){
        scanf("%d",&key);
        pos=-1;
        int idx;
        for(int j=0;j<TSize;j++){
            idx=(key+j*j)%TSize;
            if(!hashing[idx]){
                hashing[idx]=1;
                pos=idx;
                break;
            }
        }
        if(i==0){
            printf("%d",pos);
        }
        else{
            if(pos==-1)
                printf(" -");
            else
                printf(" %d",pos);
        }
    }
    return 0;
}
View Code

 

posted @ 2017-02-12 11:19  辰曦~文若  阅读(741)  评论(0编辑  收藏  举报