1. 程式人生 > 實用技巧 >雜湊表HashMap

雜湊表HashMap

沒用的定義

散列表(Hash table,也叫雜湊表),是根據關鍵碼值(Key value)而直接進行訪問的資料結構。也就是說,它通過把關鍵碼值對映到表中一個位置來訪問記錄,以加快查詢的速度。這個對映函式叫做雜湊函式,存放記錄的陣列叫做散列表。

問題引入

很簡單的例子
給一列數
然後詢問這個數字有沒有出現過

solution

陣列跑,對於過大的下標,或者極大值,正確性不能保證
map每次查詢\(O(logn)\)
雜湊表查詢為\(O(1)\)

HASH MAP

hash函式跳過不說
最簡單的就是\((a*key + b) % mod\)
對於hashmap再取一個小的mod數
看例子看例子
給一列數的hash值為

54 43 42 22

假定取小mod=11

10 10 9 0

然後建圖
0 9 10
22 42 43
54

然後像臨接表一樣儲存
例如查詢43時

for(int i = head[43 % mod]; i; i = edge[i].nxt){
      if(edge[i].val == 43) return 1;
}

就完了,確實比map快好多
開O2之後差距不大

code

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#define int long long
using namespace std;

inline int read(){
	int x = 0, w = 1;
	char ch = getchar();
	for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return x * w;
}

const int mod = 23333;
const int ss = 1000010;

struct node{
	int nxt, val;
}edge[ss + 5];

int head[ss + 5], tot;

inline void add(int u){
	int sol = u % mod;
	edge[++tot].val = u;
	edge[tot].nxt = head[sol];
	head[sol] = tot;
}

inline bool find(int u){
	int sol = u % mod;
	for(int i = head[sol]; i; i = edge[i].nxt){
		if(edge[i].val == u)
			return 1;
	}
	return 0;
}

inline void erase(int u){
	head[u % mod] = 0;
}

inline unsigned long long hash(int u){
	u *= 233;
	u %= mod;
}

signed main(){
	int n = read();
	for(int i = 1; i <= n; i++){
		int x = read();
		add(hash(x));
	}
	int cnt = read();
	while(cnt--){
		int x = read();
		if(find(hash(x))) puts("AC");
		else puts("WA");
	}
	return 0;
}