bloom filter与dawgdic(一种trie树)
我有一个做了一款移动浏览器的朋友。
他有这样一个需求:当用户输入一个站点的url时候。移动浏览器须要识别这个网址是否是一个恶意网址。另外。他有一个恶意网址库。
或许这种解决方法有多种。
当中一种就是把恶意网址库放在本地,移动浏览器拿到一个网址的时候就把它与网址库中的每一个地址匹配一下。依据匹配与否来推断网址的是否为一个恶意地址。
哦,我忘了补充的情况就是这个网址库中有150万条数据,压缩后23M。假设一个浏览器为了识别恶意网址这么一个功能而附加这么大的库,你会没实用户的。
我刚開始给出的解决方法是bloom filter(bloom过滤器)。
关于它的具体机理。吴军先生的《数学之美》中当有提及,我这里仅仅给出一些參数值:数组大小是1500000 * 20 / 8 B(即bitset大小是数据项的20倍)。hash function数目为13,误差率为万分之中的一个。我用C++和Java分别实现了这个算法。測试后效果令人惬意。数组大小仅仅有4M多,再用zip压缩后大小仅仅有2.8M。4G时代移动浏览器附带一个3M大小的库,个人以为是能够让人接受的。
事情到此为止本该就此结束。朋友又有一个需求:当用户输入一个网址的前面一部分数据库的时候。浏览器要给出相关的最多十个相关网址。
这个网址库当然就更大了。并且又要不断地更新,意味着不能放在本地。
可是,每一个人浏览的站点一般不会超过一百个吧,刚開始这个库能够为零,随着用户使用次数增多,统计一下缓存在本地就okay啦。这个不须要去server拉一大堆网址库下来。
再说,真要是匹配不到也无所谓啦。
我想到的算法是trie树。自己实现一个trie树当然是非常蠢笨的事情,我去网上搜罗了一番,在stackoverflow上得到一个提示:dawgdic。
它也自称是最棒的trie树,查找速度最快。并且声称的字典库相对来说比二维数组实现的trie树还要节省空间。我在code.google.com上下载完代码后(最新代码是dawgdic-0.4.5.tar.gz,2011年),把它的example看了一遍,有例如以下功能:
1 依据排列有序的数据,它能够构建出一个很节省空间的dawg dictionary。
2 它的dawg词典库的每一项能够仅仅有一个key,也能够附带插入其value。即每一个数据项是一个key-value对。
3 依据构建好的词典它能够进行kv查询,即给出一个key。返回其value;
4 假设仅仅能给出key的一段前缀。它能够返回全部共同前缀的key,这些结果能够依照字母顺序排列后返回也能够依照value的大小排序后返回;
5 假设仅仅能给出key的一段后缀,它能够返回全部共同后缀的key,这些结果能够依照字母顺序排列后返回也能够依照value的大小排序后返回。
依据以上特性。上面那个需求就稀里哗啦地攻克了(^_^)。我们须要利用的特性是1、2和4。dawg字典的key当然是网址的url,其权值当然是浏览次数。因为dawg词典构建好了以后,不能进行modify,而用户对每一个网址每一段时间内的浏览次数是变化的,这就须要没过一段时间内对这个dawg dictionary进行又一次构建。
事实上上面仅仅是简单地分别列举了两个算法的各自应用场景,事实上这两个算法的应用范围很广。如bloom filter就不说了,dawg树就能够用在搜索中的热搜索提示、一些英汉词典的词语搜索和输入法的个性化提示等。
晚上吃完饭,写出此记,对自己近期一段时间的业余研究做一番总结,接着加班。
附带声明:不经本人同意,诸如推酷“www.tuicool.com”这样的垃圾抄袭站点不得转载本人的blog。
版权声明:本文博客原创文章。博客,未经同意,不得转载。
bloom filter与dawgdic(一种trie树)的更多相关文章
- 双数组Trie树 (Double-array Trie) 及其应用
双数组Trie树(Double-array Trie, DAT)是由三个日本人提出的一种Trie树的高效实现 [1],兼顾了查询效率与空间存储.Ansj便是用DAT(虽然作者宣称是三数组Trie树,但 ...
- Java Bloom filter几种实现比较
英文原始出处: Bloom filter for Scala, the fastest for JVM 本文介绍的是用Scala实现的Bloom filter. 源代码在github上.依照性能测试结 ...
- 布隆过滤器(Bloom Filter)的原理和实现
什么情况下需要布隆过滤器? 先来看几个比较常见的例子 字处理软件中,需要检查一个英语单词是否拼写正确 在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上 在网络爬虫里,一个网址是否被访问过 yahoo, ...
- Bloom Filter布隆过滤器原理和实现(1)
引子 <数学之美>介绍布隆过滤器非常经典: 在日常生活中,包括设计计算机软件时,经常要判断一个元素是否在一个集合中.比如: 在字处理软件中,需要检查一个英语单词是否拼写正确(也就是要判断它 ...
- bloom filter
Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员. 结 构 二进制 召回率 ...
- 布隆过滤器(Bloom Filter)详解——基于多hash的概率查找思想
转自:http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html 布隆过滤器[1](Bloom Filter)是由布隆(Burton ...
- 1.Bloom filter
Bloom filter 是由 Howard Bloom 在 1970 年提出的二进制向量数据结构,它具有很好的空间和时间效率,被用来检测一个元素是不是集合中的一个成员,这种检测只会对在集合内的数据错 ...
- [转载] 布隆过滤器(Bloom Filter)详解
转载自http://www.cnblogs.com/haippy/archive/2012/07/13/2590351.html 布隆过滤器[1](Bloom Filter)是由布隆(Burton ...
- 布隆过滤器(Bloom Filter)详解
直观的说,bloom算法类似一个hash set,用来判断某个元素(key)是否在某个集合中.和一般的hash set不同的是,这个算法无需存储key的值,对于每个key,只需要k个比特位,每个存储一 ...
随机推荐
- Swift - 通过url地址打开web页面
通过UIApplication.sharedApplication().openURL()方法,可以使用浏览器打开相应的网页. 1 2 3 var urlString = "http://h ...
- Swift - 使用socket进行通信(附聊天室样例)
在Swift开发中,如果我们需要保持客服端和服务器的长连接进行双向的数据通信,使用socket是一种很好的解决方案. 下面通过一个聊天室的样例来演示socket通信,这里我们使用了一个封装好的sock ...
- Android开发:在onTouchEvent中处理任意时间的长按事件
Android提供了GestureDetector类来处理一些常用的手势操作,比如说 onLongPress,onFling 等.但这里不使用GestureDetector,而是直接在自定义View重 ...
- 使用JDBC处理数据库大容量数据类型
在本文将介绍如何使用JDBC操作MySQL数据库对于大容量数据类型的读取.在之前的博客中已经介绍了如何使用JDBC来操作数据库对各种数据的增删改查,那么大容量数据类型的数据操作又为何不同呢. 原因在于 ...
- java大牛list
1 Java的未来 Java能干什么.不能干什么,一开始就要搞清楚.这对于成为一个纯种的Java程序猿至关重要. 2 构建Java运行环境 Java运行在服务器,服务器都是Linux系统,对于真正程序 ...
- Swift - 导航条(UINavigationBar)的使用
与导航控制器(UINavigationController)同时实现导航条和页面切换功能不同. 导航条(UINavgationBar)可以单独使用,添加至任何的UIView中.UINavigation ...
- [置顶] Embedded Server:像写main函数一样写Web Server
1.传统的JEE Web Server 传统的JEE中,如果我们想要部署一个Web Application,我们需要首先安装一个Container Server,如JBoss,WebLogic,Tom ...
- C 文件直接包含
C 文件直接包含 有一部分代码很大,在很多函数中重复,可以直接写在另外的一个文件中,引用时直接包含.co.cpp两个函数都 包含c1.cxx. 点击(此处)折叠或打开 ////// co.cpp #i ...
- Eclipse代码字体、颜色美化,更改字体大小、颜色
先看效果: 感觉如何,是否比你的eclipse编辑器显示的代码要漂亮简洁呢?呵呵.这个是我原来ADT Eclipse的效果,现在去下居然更新掉了,找不到了.于是我就参照我原来的配置对这个新的Eclip ...
- Java编码浅析(注意区分三个概念)(转)
编码: (1)外部资源的字符集-----没有读入jvm中的数据都是外部资源 (2)jvm中数据的字符集-----都是unicode (1)和(2)之间发生交互时,如果不指定编码,则使用JVM平台默认字 ...