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

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

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 \% TSizeH(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;
}
目录
相关文章
|
C++
【PAT甲级 - C++题解】1040 Longest Symmetric String
【PAT甲级 - C++题解】1040 Longest Symmetric String
66 0
|
算法 C++
【PAT甲级 - C++题解】1044 Shopping in Mars
【PAT甲级 - C++题解】1044 Shopping in Mars
82 0
|
C++
【PAT甲级 - C++题解】1117 Eddington Number
【PAT甲级 - C++题解】1117 Eddington Number
77 0
|
存储 C++ 容器
【PAT甲级 - C++题解】1057 Stack
【PAT甲级 - C++题解】1057 Stack
76 0
|
存储 C++
【PAT甲级 - C++题解】1055 The World‘s Richest
【PAT甲级 - C++题解】1055 The World‘s Richest
79 0
|
C++
【PAT甲级 - C++题解】1051 Pop Sequence
【PAT甲级 - C++题解】1051 Pop Sequence
80 0
|
6天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
30 5
|
13天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
42 4
|
14天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
40 4
|
1月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
28 4