Kingsman C++ハッシュテーブル知識点
8843 ワード
一般ハッシュ
(1)ファスナー法
(2)オープンアドレス方式
文字列ハッシュ
核心思想:文字列をP進数と見なして、Pの経験値は131あるいは13331で、この2つの値の衝突確率の低い小さい技巧を取ります:型を取る数は2^64で、このように直接unsigned long longで記憶して、あふれ出す結果は型を取る結果です
(1)ファスナー法
int h[N], e[N], ne[N], idx;
//
void insert(int x)
{
int k = (x % N + N) % N;
e[idx] = x;
ne[idx] = h[k];
h[k] = idx ++ ;
}
//
bool find(int x)
{
int k = (x % N + N) % N;
for (int i = h[k]; i != -1; i = ne[i])
if (e[i] == x)
return true;
return false;
}
(2)オープンアドレス方式
int h[N];
// x , x ; x , x
int find(int x)
{
int t = (x % N + N) % N;
while (h[t] != null && h[t] != x)
{
t ++ ;
if (t == N) t = 0;
}
return t;
}
文字列ハッシュ
核心思想:文字列をP進数と見なして、Pの経験値は131あるいは13331で、この2つの値の衝突確率の低い小さい技巧を取ります:型を取る数は2^64で、このように直接unsigned long longで記憶して、あふれ出す結果は型を取る結果です
typedef unsigned long long ULL;
ULL h[N], p[N]; // h[k] k , p[k] P^k mod 2^64
//
p[0] = 1;
for (int i = 1; i <= n; i ++ )
{
h[i] = h[i - 1] * P + str[i];
p[i] = p[i - 1] * P;
}
// str[l ~ r]
ULL get(int l, int r)
{
return h[r] - h[l - 1] * p[r - l + 1];
}