OVSolitario-io

导航

Hash

求最小冲突质数
探究P本质
对于偶数,%6结果只能为0,2,4(w[]利用率低),而对于%5则为1,2,3,4,5
所以当p为质数时最大有效

for(int i = 100000; ; ++ i)
    {
        bool flag = true;
        for(int j = 2; j * j <= i; ++ j)
            if(i % j == 0) {
                flag = false;
                break;
            }
        if(flag) {
            cout << i << endl;
            break;
        }

这里引入问题:

截屏2024-08-19 21.03.32

brute1(时间上)
截屏2024-08-19 21.06.20

思路:用数据结构(1/2/3) + 排序二分
1.map维护表nlogn
2.用trie树:线性,只有13位可以很高效的解决问题
3.手写平衡树来维护信息

取模:进行取模操作(最朴素的hash方案)
截屏2024-08-19 21.24.37
但若同余则会发生碰撞

Hash
hash函数:将大值域压缩到小值域

Hash冲突:原值不相同,取模后的值相同的情况叫为“xoi:哈希碰撞”。

5%2333333 <=> 2333338%2333333,发生冲突

解决碰撞: 将模数P增大,P越大碰撞概率越稀疏
假设P = 2,则每两个数都有一半概率碰撞,P = 100w,则每两个数碰撞的概率只有1/100W
截屏2024-08-19 23.59.14

  • 取双模数:只有两个取模数都指向这个值时,我们认为它存在

双模数降低碰撞,两模数都取质数保证:a*b范围内都是有效的

(一般只有在字符串hash时才写双模hash)

相当于两个检验器,当且仅当两个检验器都为1,才为1

但依然可能会发生碰撞,双模数降低了碰撞,但碰撞还具有存在性

探究P本质截屏2024-08-20 00.32.17
对于偶数,%6结果只能为0,2,4(w[]利用率低),而对于%5则为1,2,3,4,5

所以当p为质数时最大有效

解决Hash冲突的几种方法:
截屏2024-08-19 22.54.05

拉链法:拉链存%p的all余数,查找时遍历这个链

点击查看代码
#include <cstdio>
#include <vector>
using namespace std;

#define mod 233333//定义模数

struct zip {
    vector<int> w[mod + 5];
    void ins(int x) {
        w[x % mod].push_back(x);//此时即将x加入到其hash值x%mod序列的结尾     
    }
    void ask(int x) {
        //查询时扫一遍vector
        for(auto i = w[x % mod].begin(); i != w[x % mod].end(); ++ i)
            if(*i == x)//如果恰好等于我们要查询的x
                goto done;
        puts("No");
        return ;

        done :
        puts("Yes");
    }
};

zip B;
int main(void) {
    B.ask(5);
    B.ins(5);
    B.ask(5);

    B.ask(5 + mod);
    B.ins(5 + mod);
    B.ask(5 + mod);
}

STL大法:unordered_set好处是任意类型,O(1)查询,内部实现是一个拉链法

点击查看代码
#include <cstdio>
#include <vector>
#include <unordered_set>
using namespace std;

#define mod 233333//定义模数

unordered_set<int> S;

int main(void) {
    printf("%d\n", S.count(5));
    S.insert(5);
    printf("%d\n", S.count(5));//返回有几个5,一般返回5是否在其中
}

unorder_set可能不支持结构体,但set支持结构体,set的底层实现是一棵红黑树(平衡树一种),unordered_set底层实现为hash

set是有序表,所以可以开结构体类型(前提为结构体定义了小于号)
一般hash可以用set,也可以用unordered_set

线性探测法:蹲坑法?即位置x已有,则看x+1,x+2····直到找到一个为空的位置

平方探测法:若x有东西,则看x2%p是否有东西,看x3%p是否有东西····依次

posted on 2025-09-27 10:31  TBeauty  阅读(4)  评论(0)    收藏  举报