在生活中,包括在设计计算机软件时,经常要判断一个元素是否在一个集合中,最直接的办法就是将全部元素都存在计算机中,遇到一个新元素,将它与集合中的元素比较即可。一般来讲,计算机中的集合是使用哈希表来存储的。它的好处是快速而准确,缺点是费存储空间。当集合比较小时,这个问题不显著,但当集合非常巨大时,哈希表存储效率低的问题就体现出来了。
一种称为布隆过滤器的数学工具,它只需要哈希表的1/8到1/4的大小就能解决同样的问题。它是使用bloom filter算法实现的,用java代码实现如下:
package net.csdn.diu_brother;
import java.util.BitSet;
public class SimpleBloomFilter{
private static final int DEFAULT_SIZE = 2<<24;
private static final int[] seeds = new int[]{7,11,13,31,37,61};
private BitSet bits = new BitSet(DEFAULT_SIZE);
private SimpleHash[] func = new SimpleHash[seeds.length];
public static void main(String[] args){
String value = "stone2083@yahoo.cn";
SimpleBloomFilter filter = new SimpleBloomFilter();
System.out.println(filter.contains(value));
filter.add(value);
System.out.println(filter.contains(value));
}
public SimpleBloomFilter(){
for(int i=0;i<seeds.length;i++){
func[i] = new SimpleHash(DEFAULT_SIZE,seeds[i]);
}
}
public void add(CrawlUrl value){
if(value!=null){
add(value.getOriUrl());
}
}
public void add(String value){
for(SimpleHash f:func){
bits.set(f.hash(value),true);
}
}
public boolean contains(CrawlUrl value){
return contains(value.getOriUrl());
}
public boolean contains(String value){
if(value==null){
return false;
}
boolean ret =true;
for(SimpleHash f:func){
ret = ret && bits.get(f.hash(value));
}
return ret;
}
public static class SimpleHash{
private int cap;
private int seed;
public SimpleHash(int cap,int seed){
this.cap = cap;
this.seed = seed;
}
public int hash(String value){
int result = 0;
int len = value.length();
for(int i=0;i<len;i++){
result = seed*result+value.charAt(i);
}
return (cap-1)&result;
}
}
}