PTA11-散列2 Hashing

本文介绍了如何使用哈希表插入一系列唯一正整数,并输出它们的位置。哈希函数定义为H(key)=key%TSize,其中TSize是最大哈希表大小。当发生冲突时,采用平方探测法解决。如果用户给出的最大表大小不是素数,我们需要找到大于该数的最小素数作为表大小。文章通过示例输入和输出展示了具体实现过程,并解释了何时无法将数字插入哈希表的情况。
摘要由CSDN通过智能技术生成

PTA11-散列2 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.

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 -
结尾无空行

思路

1.获得比Tablesize大的最小素数

质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数(规定1既不是质数也不是合数)。

特例:1,对1来说,他不是素数(质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数),所以对他而言最小素数为2。

算法描述:
(1)设置p为最小的奇数
(2)i从sqrt§到2,一直进行判断,i–
(3)如果有p%i==0,即p和i是整数倍的则跳出循环
(4)判断一下跳出循环的i,若i不为1,则说明p能被其他自然数整除,不是质数,p+=2(下一个奇数)
(5)若i=1,为质数,跳出循环

2.什么情况下没有放入hash表的机会,要print("-")
当增量为TableSize2时,可以把TableSize2对TableSize取余,发现为0。
然后再看(TableSize+1)2对TableSize取余,发现为1。
继续下去可以发现,当超过TableSize时,如TableSize+a取余结果就是a,因此我们循环只需要到TableSize就可以结束。

Code

#include<iostream>
#include<math.h>
using namespace std;
//获得大于等于TableSize最小的素数
int getMaxPrime(int x){
    if(x==1){
        return 2;
    }
    int p=(x%2==1)?x:x+1;//最小的奇数
    while(1){
        int i;
        for(i=sqrt(p);i>=2;i--){
            if(p%i==0){
                break;
            }
        }
        if(i==1){
            break;
        }else{
            p+=2;
        }
    }
    return p;
}
int hash_key(int key,int TableSize){
    return key%TableSize;
}

int main(){
    int TableSize,M,key;
    scanf("%d %d",&TableSize,&M);
    TableSize=getMaxPrime(TableSize);
    int Hash[TableSize];
    for(int i=0;i<TableSize;i++){
        Hash[i]=-1;
    }
    for(int i=0;i<M;i++){
        scanf("%d",&key);
        int pos=hash_key(key,TableSize);
        if(i!=0){
            printf(" ");
        }
        if(Hash[pos]==-1){//第一次探测就可以放
            Hash[pos]=key;
            printf("%d",pos);
        }else{//需要平方探测TableSize次为止
            int temppos,flag=0;
            for(int cnt=1;cnt<TableSize;cnt++){
                temppos=pos+cnt*cnt;
                temppos=hash_key(temppos,TableSize);//注意此处为temppos=,不能修改pos
                if(Hash[temppos]==-1){
                    flag=1;
                    Hash[temppos]=key;
                    printf("%d",temppos);
                    break;
                }
            }
            if(flag==0){
                printf("-");
            }
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值