【PAT甲级 - C++题解】1078 Hashing

✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
📚专栏地址:PAT题解集合
📝原题地址:题目详情 - 1078 Hashing (pintia.cn)
🔑中文翻译:哈希
📣专栏定位:为想考甲级PAT的小伙伴整理常考算法题解,祝大家都能取得满分!
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

1078 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 ( k e y ) = k e y % T S i z e H(key)=key \% TSize 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 (≤104) 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 -
题意

这道题给定一个表的大小以及元素的个数,我们需要利用二次探测法来计算每个元素在表中的位置,如果能找到对应位置则输出对应位置的下标,反之输出 - 。另外,表的大小必须为质数,如果给定的不是质数,则需要求出大于该值的最小质数当做表长。

关于什么是二次探测法,我在之前的 C++ 实现查找的博客中有详细讲解,传送门如下:

(239条消息) C++实现查找 - 顺序、二分和哈希查找_Pandaconda的博客-CSDN博客_顺序查找c++

思路

思路如下:

  1. 判断表长是否为质数,如果不是则递增表长,直至找到大于给定表长的第一个质数。
  2. 查找给定元素在表中的下标位置,通过二次探测法解决哈希冲突,如果能找到一个位置则返回该下标,否则返回 -1
  3. 根据查找的结果更新哈希表中的值,并输出相应结果。
代码
#include<bits/stdc++.h>
using namespace std;

const int N = 10010;
int h[N];
int m, n;

//判断x是否为质数
bool is_prime(int x)
{
    if (x == 1)    return false;

    for (int i = 2; i * i <= x; i++)
        if (x % i == 0)
            return false;

    return true;
}

//用二次探测法计算位置
int find(int x)
{
    int t = x % m;
    for (int k = 0; k < m; k++)
    {
        int i = (t + k * k) % m;
        if (!h[i])   return i;
    }
    return -1;
}

int main()
{
    cin >> m >> n;

    //先确保m为质数
    while (!is_prime(m))  m++;

    //判断数字能否插入到表中
    for (int i = 0; i < n; i++)
    {
        int x;
        cin >> x;

        //计算是否能找到插入位置
        int t = find(x);
        if (t == -1)   cout << "-";
        else
        {
            h[t] = x;
            cout << t;
        }

        //末尾不能有空格
        if (i != n - 1)  cout << " ";
    }

    return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值