数据结构-2020夏 11-散列2 Hashing (25分)

原题地址

https://pintia.cn/problem-sets/1268384564738605056/problems/1294124786527993857

解题思路

没有用课堂上很复杂的结构体定义啥的~

注意到题目中给的都是严格的正整数(distinct positive integers),所以就偷懒直接开了一个数组,初始状态所有元素为0,代表这个单元没有元素~

之后就常规操作就可以了!

注意事项

0.审题~题目的平方探测法只要正向的(with positive increments only)。

1.查找位置时的更新写法。
正确写法类似

newPos = pos + pow(++cnum, 2);

一开始的时候忘记每次是在原来的pos基础上去加平方了!

2.注意特判n=1的情况。

做的时候有一个测试点没过,是最小N,也就是N=1的时候。这里要注意,1不是素数,但是我们求下一个素数的函数时,默认是直接判断该数的奇偶性,奇数+2,偶数+1,那么1就比较特殊,1只要+1就可以得到比它大的素数2了~

参考代码

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef double db;
typedef long long LL;
typedef vector<int> VI;
const int inf = 2e9;
const LL INF = 8e18;
const int maxn = 5e5 + 5;

int* hashTable;

bool isPrime(int n) {
	if (n <= 2) return false;
	for (int i = (int)sqrt(n); i >= 2; i--) {
		if (n % i == 0) return false;
	}
	return true;
}

int nextPrime(int n) {
	if (n == 1) return 2;  //1要特判 
	int p = (n % 2) ? n + 2 : n + 1;  //p为奇数的话,+2,否则+1 
	int i;
	while (1) {
		for (i = (int)sqrt(p); i > 2; i--) {  //因为p是奇数,故i>2即可 
			if (p % i == 0) break; 
		}
		if (i == 2) break;  //若循环结束,说明是素数 
		else p += 2;
	}
	return p;
}

int hashF(int key, int size) {
	return key % size;
}

int find(int key, int size) {
	int newPos, pos = hashF(key, size);
	newPos = pos;
	if (hashTable[pos]) {  //若该位置有元素了 
		int cnum = 0;
		while (hashTable[newPos]) {
			newPos = pos + pow(++cnum, 2);
			newPos %= size;
			if (cnum > size) return -1; 
		}
		return newPos;
	} else return pos;
}

void insert(int key, int size) {
	int pos = find(key, size);
	if (pos != -1) {
		hashTable[pos] = key;
		printf("%d", pos);
	}
	else printf("-");
}

int main() {
	int n, m, size;
	scanf("%d%d", &n, &m);
	if (isPrime(n)) size = n;  //若n是素数,size直接等于n 
	else size = nextPrime(n);
	hashTable = (int*)malloc(size * sizeof(int));
	memset(hashTable, 0, sizeof(hashTable));
	int k;
	for (int i = 0; i < m; i++) {
		if (i) printf(" ");
		scanf("%d", &k);
		insert(k, size);
	}
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值