哈希表模板

拉链法

JLOI2011 不重复数字

const int SZ = 100007;
struct hash_table
{
    int head[SZ], next[SZ], key[SZ], val[SZ];
    int cnt;
    void init()
    {
        cnt = 0;
        memset(head, -1, sizeof(head));
    }

    int hash(int k)
    {
        return (k % SZ + SZ) % SZ;
    }

    int count(int k)
    {
        int hu = hash(k);
        for(int i = head[hu]; i != -1; i = next[i])
            if(key[i] == k)
                return i;
        return -1;
    }

    int& operator[](int k)
    {
        int idx = count(k);
        if(idx != -1){
            return val[idx];
        }else{
            int hu = hash(k);
            key[cnt] = k;
            next[cnt] = head[hu];
            head[hu] = cnt;
            return val[cnt++];
        }
    }
}tb;

字符串哈希

先将字符串转化为一个数再进行Hash,把字符串看作一个 \(p\) 进制的数且保证 \(p\) 大于所有字符的 \(ACSII\) 码即可,在这里我们取 \(p=131\)

自然溢出法

与模数为 \(2^{64}\) 的单Hash法相同

const int BASE = 131;
ull hashs(string s)
{
    int len = s.size();
    ull res = 0;
    for(int i = 0; i < len; i++)
        res = res * BASE + s[i];
    return res;
}
单Hash法

模数选择一个 \(10^{18}\) 的质数防止冲突

const int BASE = 131;
const ull MOD = 2123704413013795711;
ull hashs(string s)
{
    int len = s.size();
    ull res = 0;
    for(int i = 0; i < len; i++)
        res = (res * BASE + s[i]) % MOD;
    return res;
}
双Hash法

对一个字符串进行两次模数不同的单Hash,对于两个不同的字符串,只有当他们两次Hash的结果都相等时才会冲突,最为稳妥的做法

const int BASE = 131;
const int MOD1 = 19260817;
const int MOD2 = 19660813;

ull hash1(string s)
{
    int len = s.size();
    ull res = 0;
    for(int i = 0; i < len; i++)
        res = (res * BASE + s[i]) % MOD1;
    return res;
}

ull hash2(string s)
{
    int len = s.size();
    ull res = 0;
    for(int i = 0; i < len; i++)
        res = (res * BASE + s[i]) % MOD2;
    return res;
}
模板(自然溢出法)

P3370 字符串哈希

#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;

const int MAX_N = 10000 + 5;
const int BASE = 131;
ull h[MAX_N];

ull hashs(string s)
{
    int len = s.size();
    ull res = 0;
    for(int i = 0; i < len; i++)
        res = res * BASE + s[i];
    return res;
}

int main()
{
    int n, ans = 0;
    cin >> n;
    for(int i = 1; i <= n; i++) {
        string s;
        cin >> s;
        h[i] = hashs(s);
    }
    sort(h + 1, h + n + 1);
    for(int i = 1; i <= n; i++)
        if(h[i] != h[i - 1])
            ans++;
    cout << ans << endl;
    return 0;
}
posted @ 2021-12-25 11:31  f(k(t))  阅读(53)  评论(0编辑  收藏  举报