布隆算法实现url消重

常用url消重算法:
    1 基于hash算法的存储
    对于每个给定的url,都是用一个已经建立好的hash算法把它映射到某个物理地址上,当我们要检验某个url是否存在时只要将这个url进行hash映射,如果映射后的地址已经存在,则说明当前这个url已经存在。否则将url和它所映射的地址作为键值对放入一个hash表中,这就需要我们设计的hash函数很好,不然在映射的过程中发生较多的冲突就会对结果照成影响。另一方面,我们将url作为键,而url的字符串也浪费了比较大的空间,显然,对于较多的url消重,这种方法并不适合。
    2 基于布隆过滤器算法的消重
    布隆过滤器是一个非常好的数据结构,它实际上是一个很长的二进制向量和一系列随即映射函数,它可以用来检测一个元素是否在一个集合中,后来也被用到表示网页的url上。
    使用布隆过滤器的优劣:
    优点:它的空间效率和查询时间都高于一般的算法。
    缺点:有一定的误识别率。(虽然有一定的误识别率,但在大量的信息搜索中,它还是一种比较好的方法)
布隆算法的基本思想:
1 设一个数据集合A={... ...}中有n个元素。
2 用一个长度为m的位向量表示V表示集合中的元素,并初始化为0。
3 写好k个具有均匀分布特性的散列函数。
4 对于元素的加入操作首先通过k个散列函数产生k个随即数h1,h2,h3... ...hk,并将V集合中对应的h1,h2... ... hk的位置置为1。查找操作同理,对于要查找的元素先通过散列函数得到k个随机数,然后判断V集合中这k个位置是否为1,如果为1则说明该元素已经有了。
误判率的计算:
  上面已经说了这种算法存在一定的误判率,那该如何将这种误判率降到最小呢?
  设m为bit数,n为元素个数,k为散列函数的个数,当k = 0.7 * m/n时算法的误判率最小。(具体证明省略)
  基于布隆算法的网页url消重的实现:

import java.util.BitSet;

public class BloomFilterTest {

	private BitSet bits;
	private int defaultsize = 2 << 24;
	private int basicsize = defaultsize - 1;

	public BloomFilterTest() {
		this.bits = new BitSet(defaultsize);
	}

	public void add(String url) {
		if (url == null) {
			return;
		}
		int pos1 = hash1(url);
		int pos2 = hash1(url);
		int pos3 = hash1(url);
		bits.set(pos1);
		bits.set(pos2);
		bits.set(pos3);
	}

	public boolean contains(String url) {
		if (url == null) {
			return true;
		}
		int pos1 = hash1(url);
		int pos2 = hash1(url);
		int pos3 = hash1(url);
		if (bits.get(pos1) && bits.get(pos2) && bits.get(pos3)) {
			return true;
		}
		return false;
	}

	public int hash1(String line) {
		int h = 0;
		for (int i = 0; i < line.length(); i++) {
			h = h * 31 + line.charAt(i);
		}
		return check(h);
	}

	public int hash2(String line) {
		int h = 0;
		for (int i = 0; i < line.length(); i++) {
			h = h * 33 + line.charAt(i);
		}
		return check(h);
	}

	public int hash3(String line) {
		int h = 0;
		for (int i = 0; i < line.length(); i++) {
			h = h * 37 + line.charAt(i);
		}
		return check(h);
	}

	public int check(int h) {
		return basicsize & h;
	}

	public void test() {
		String urls[] = { "www.baidu.com", "www.google.com", "www.sina.com",
				"www.renren.com", "www.sohu.com" };
		for (int i = 0; i < urls.length; i++) {
			add(urls[i]);
		}
		String testUrls[] = { "www.google.com", "www.dangdang.com",
				"www.360buy.com", "www.baidu.com" };
		for (int i = 0; i < testUrls.length; i++) {
			if (contains(testUrls[i])) {
				System.out.println("找到匹配的网址: " + testUrls[i]);
			} else {
				System.out.println("未找到匹配的网址");
			}
		}
	}
}

public class MainBloomFilter {
	public static void main(String[] args) {
		BloomFilterTest bft = new BloomFilterTest();
		bft.test();
	}
}

 测试结果:
找到匹配的网址: www.google.com
未找到匹配的网址
未找到匹配的网址
找到匹配的网址: www.baidu.com

猜你喜欢

转载自lsx111.iteye.com/blog/1820502