哈希函数与哈希表
哈希函数的性质
哈希函数不随机,只要是相同的输入参数,结果一定相同.
定义上哈希函数输入域无穷,输出域有穷.
哈希碰撞为不同输入产生相同输出,哈希碰撞产生概率极低.
哈希函数的应用
现在有一个大文件,其中全为无符号整数0~2^32-1,现在你仅有1g内存,请寻找其中出现次数最多的无符号整数
题解
分析可得改文件要直接存入哈希表中需要32g内存,所以不可直接用暴力解法,在文件处理上我们可以使用哈希函数的性质,先将文件均匀分类再模100可以得到100个子文件,由于哈希函数的性质,同一个数会被分到一个子文件当中,在这100个子文件中我们仅需统计每个子文件中出现频率最高的那个数,共100个数然后进行比较即可.
哈希表
设计RandomPool结构
import java.util.HashMap;
public class RandomPool<K> {
private HashMap<K,Integer> keyIndexMap;
private HashMap<Integer,K> IndexkeyMap;
private int size;
public RandomPool(){
this.keyIndexMap = new HashMap<K,Integer>();
this.IndexkeyMap = new HashMap<Integer,K>();
this.size = 0;
}
public boolean insert(K key){
if (this.keyIndexMap.containsKey(key)){
return false;
}
this.keyIndexMap.put(key,this.size);
this.IndexkeyMap.put(this.size,key);
this.size++;
return true;
}
public boolean delete(K key){
if(!this.keyIndexMap.containsKey(key))
return false;
int deleteIndex = this.keyIndexMap.get(key);
int lastIndex = --this.size;
K lastKey = this.IndexkeyMap.get(lastIndex);
this.IndexkeyMap.put(deleteIndex,lastKey);
this.keyIndexMap.put(lastKey,deleteIndex);
this.keyIndexMap.remove(key);
this.IndexkeyMap.remove(lastIndex);
return true;
}
public K getRandom(){
if(this.size == 0){
return null;
}
int randomIndex = (int)(Math.random()*this.size);
return this.IndexkeyMap.get(randomIndex);
}
}
布隆过滤器
布隆过滤器的实现需要一个长度为m的bit数组,当有一个url需要添加进黑名单时,我们要用k个哈希函数并模m得到一个数字,将bit数组中的m位置描黑,就相当于添加了一个黑名单.
在这种条件下不会出现黑名单变白名单,但有可能白名单会成黑名单,就是所谓的失误.
单样本量大小不影响布隆过滤器
布隆过滤器失误率分析
设n为样本量,p为失误率
则m(需要开辟的bit数组长度)=-(n*lnp)/(ln2)^2,需要向上取整
则k(所需要的哈希函数)=ln2*m/n,需要向上取整
则p真=(1-e((-n*k真)/m真))k真
详解一致性哈希
写的完全不如人家白话,就看人家的得了
https://www.zsythink.net/archives/1182