1078 Hashing (25分)

1 题目

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 -

2 解析

2.1 题意

给出表长m(如果不是素数,转变为比m大的最小素数)和欲插入的元素,用平方探测法(只正向递增)解决冲突进行插入表中,问如果能插入输出“Yes”,否则输出“No”。

2.2 思路

平方探测法:当 d i = 0 2 , 1 2 , − 1 2 , 2 2 , − 22 , . . . , k 2 , − k 2 d_{i} =0^{2},1^{2},-1^{2},2^{2},-2{2},...,k^{2},-k^{2} di=02,12,12,22,22,...,k2,k2时,称为平方探测法,其中 k ≤ m / 2 k\leq m/2 km/2,散列平方探测法是一种较好的处理冲突的方法,可以避免出现“堆积“问题,它的缺点在于不能探测到散列表上的所有单元,但至少能探测一半单元。

二次探测法(只正向递增):冲突处理公式为
M = ( a + s t e p ∗ s t e p ) % T S i z e M = (a+step*step)\%TSize M=(a+stepstep)%TSize
其中step为step为增量(初值为1),Tsize为表长,a为第一次欲插入的位置。step的上限为TSize,[0,Tsize - 1)。

证明step的上限为TSize:

这里只需证明step取TSize到2TSize-1也无法找到位置:
0 ≤ x < T S i z e 0 \leq x <TSize 0x<TSize,那么

( a + ( T S i z e + x ) ∗ ( T S i z e + x ) ) % T S i z e = ( a + T S i z e ∗ T s i z e + 2 ∗ T S i z e ∗ x + x ∗ x ) % T S i z e = a ( a + x ∗ x ) % T S i z e + T S i z e ∗ T S i z e % T S i z e + s ∗ T S i z e ∗ x % T S i z e = ( a + x ∗ x ) % T S i z e (a+(TSize + x)*(TSize+x))\%TSize\\ =(a+TSize*Tsize+2*TSize*x + x*x)\%TSize\\ = a(a+x*x)\%TSize+TSize *TSize \%TSize+s*TSize*x\%TSize\\ =(a + x*x)\%TSize (a+(TSize+x)(TSize+x))%TSize=(a+TSizeTsize+2TSizex+xx)%TSize=a(a+xx)%TSize+TSizeTSize%TSize+sTSizex%TSize=(a+xx)%TSize

由于所有循环节为TSize,如果step从0~TSzie进行枚举仍然无法找到位置,那么step大于等与TSize来说也不可能找到位置。

3 参考代码

#include <cstdio>
#include <cmath>
#include <cstring>

const int MAXN = 10100;
bool hash[MAXN];

bool isPrime(int n){
    if(n <= 1) return false;
    int sqr = (int)sqrt(1.0*n);
    for (int i = 2; i <= sqr; ++i)
    {
        if(n % i == 0) return false;
    }
    return true;
}

int main(int argc, char const *argv[])
{
    memset(hash, false, sizeof(hash));

    int m ,n;
    scanf("%d%d", &m, &n);

    while(isPrime(m) == false){
        m++;
    }
    
    int num;
    for (int i = 0; i < n; ++i)
    {
        scanf("%d", &num);
        int pos = num % m;
        if(hash[pos] == false){
            hash[pos] = true;
            printf("%d", pos);
        }else{
            int step = 1;
            for (; step < m; ++step)
            {
                if(hash[(pos + step*step)%m] == false){//平方二次探测法
                    hash[(pos + step*step)%m] = true;
                    printf("%d", (pos + step*step)%m);
                    break;
                }
            }
            if(step >= m){
                printf("-");
            }
        }

        if(i < n - 1) printf(" ");
    }

    return 0;
}
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 岁月 设计师:pinMode 返回首页