布谷鸟过滤器详解

布谷鸟过滤器是一种高效的数据结构,主要用于判断一个元素是否存在于一个集合中。它基于哈希表实现,以空间换时间,具有优秀的时间和空间复杂度。本文将从应用场景、原理、实现方式、优缺点等多个方面详细阐述布谷鸟过滤器。

一、应用场景

布谷鸟过滤器常用于需要判断元素是否存在于一个集合中的场景。比如:

1. 网络爬虫去重

  
import hashlib
import requests

class UrlManager(object):
    def __init__(self):
        self.url_dict = {}

    def add_new_url(self, url):
        hash_value = self._get_hash_value(url)
        self.url_dict[hash_value] = url

    def has_new_url(self, url):
        hash_value = self._get_hash_value(url)
        if hash_value in self.url_dict:
            return True
        else:
            return False

    def _get_hash_value(self, url):
        md5 = hashlib.md5()
        md5.update(url.encode('utf-8'))
        hash_value = md5.hexdigest()
        return hash_value

url_manager = UrlManager()
url_manager.add_new_url('https://www.baidu.com')
url_manager.has_new_url('https://www.baidu.com')
  

2. 黑名单过滤

  
import bloomfilter

def load_black_list(file_path):
    bf = bloomfilter.BloomFilter(1000000, 0.01)
    with open(file_path, 'r') as f:
        for line in f:
            bf.add(line.strip())
    return bf

black_list = load_black_list('/path/to/black_list.txt')
if black_list.is_contain('12345'):
    print('12345 is in black list')
  

二、原理

布谷鸟过滤器基于哈希表实现。哈希表可以用于快速查找元素,但是它并不能很好地解决散列冲突问题。针对散列冲突的解决方法有:

1. 链式法

即将哈希值相同的元素加到同一个链表中。但是当哈希值相同的元素很多时,链表会变得很长,查询效率会变得很低。

2. 开放地址法

即依次查找哈希值相邻的位置,直到找到一个空位置或是遍历完整个哈希表。但是当哈希表被填满时,开放地址法的效率会急剧下降。

为了解决上述问题,布谷鸟过滤器采用多哈希函数的方式,将元素存放在多个位置上。当查询元素时,只要有一个哈希函数返回该元素不在集合中,则判定该元素不在集合中。

三、实现方式

布谷鸟过滤器的核心是哈希函数。由于哈希函数决定了元素存放的位置,因此,选择一个好的哈希函数非常重要。常见的哈希函数有:

1. MurmurHash

一种高效的哈希算法,速度快,效果也不错,通常被用于哈希表和布隆过滤器中。

  
import mmh3

class BloomFilter(object):
    def __init__(self, size, hash_count):
        self.size = size
        self.hash_count = hash_count
        self.bit_array = [False] * size

    def add(self, key):
        for seed in range(self.hash_count):
            index = mmh3.hash(key, seed) % self.size
            self.bit_array[index] = True

    def is_contain(self, key):
        for seed in range(self.hash_count):
            index = mmh3.hash(key, seed) % self.size
            if self.bit_array[index] == False:
                return False
        return True
  

2. DJB2Hash

一种简单的哈希算法,适用于小数据。相比于MurmurHash,它的效率要低一些。

  
class BloomFilter(object):
    def __init__(self, size, hash_count):
        self.size = size
        self.hash_count = hash_count
        self.bit_array = [False] * size

    def add(self, key):
        for seed in range(self.hash_count):
            index = self._djb2(key + str(seed)) % self.size
            self.bit_array[index] = True

    def is_contain(self, key):
        for seed in range(self.hash_count):
            index = self._djb2(key + str(seed)) % self.size
            if self.bit_array[index] == False:
                return False
        return True

    def _djb2(self, key):
        hash = 5381
        for i in range(len(key)):
            hash = ((hash << 5) + hash) + ord(key[i])
        return hash & 0xffffffffffffffff
  

四、优缺点

优点:

1. 布谷鸟过滤器具有高效的查询速度,比另一种常用的过滤器——布隆过滤器的查询速度更快。

2. 布谷鸟过滤器占用的空间更少,因为布谷鸟过滤器中的元素存储在多个位置上,并且哈希函数的种类比布隆过滤器多,因此误判率也会更低。

缺点:

1. 布谷鸟过滤器的哈希函数的数量影响到了空间占用和误判率的平衡。哈希函数的数量越多,误判率越低,空间占用越多。

2. 如果需要删除布谷鸟过滤器中的某个元素,需要使用到其它的技术,比如双重哈希删除。

五、小结

布谷鸟过滤器是一种高效的数据结构,可用于判断元素是否存在于一个集合中。它通过多哈希函数的方式,将元素存放在多个位置上,具有优秀的时间和空间复杂度。哈希函数的选择非常重要,不同的哈希函数会影响误判率和空间占用。布谷鸟过滤器的应用场景非常广泛,比如在爬虫去重、黑名单过滤等方面均有巨大的作用。

原创文章,作者:HDUMO,如若转载,请注明出处:https://www.506064.com/n/372309.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
HDUMOHDUMO
上一篇 2025-04-24 06:40
下一篇 2025-04-24 06:40

相关推荐

  • Linux sync详解

    一、sync概述 sync是Linux中一个非常重要的命令,它可以将文件系统缓存中的内容,强制写入磁盘中。在执行sync之前,所有的文件系统更新将不会立即写入磁盘,而是先缓存在内存…

    编程 2025-04-25
  • 神经网络代码详解

    神经网络作为一种人工智能技术,被广泛应用于语音识别、图像识别、自然语言处理等领域。而神经网络的模型编写,离不开代码。本文将从多个方面详细阐述神经网络模型编写的代码技术。 一、神经网…

    编程 2025-04-25
  • Linux修改文件名命令详解

    在Linux系统中,修改文件名是一个很常见的操作。Linux提供了多种方式来修改文件名,这篇文章将介绍Linux修改文件名的详细操作。 一、mv命令 mv命令是Linux下的常用命…

    编程 2025-04-25
  • Python输入输出详解

    一、文件读写 Python中文件的读写操作是必不可少的基本技能之一。读写文件分别使用open()函数中的’r’和’w’参数,读取文件…

    编程 2025-04-25
  • nginx与apache应用开发详解

    一、概述 nginx和apache都是常见的web服务器。nginx是一个高性能的反向代理web服务器,将负载均衡和缓存集成在了一起,可以动静分离。apache是一个可扩展的web…

    编程 2025-04-25
  • MPU6050工作原理详解

    一、什么是MPU6050 MPU6050是一种六轴惯性传感器,能够同时测量加速度和角速度。它由三个传感器组成:一个三轴加速度计和一个三轴陀螺仪。这个组合提供了非常精细的姿态解算,其…

    编程 2025-04-25
  • 详解eclipse设置

    一、安装与基础设置 1、下载eclipse并进行安装。 2、打开eclipse,选择对应的工作空间路径。 File -> Switch Workspace -> [选择…

    编程 2025-04-25
  • Python安装OS库详解

    一、OS简介 OS库是Python标准库的一部分,它提供了跨平台的操作系统功能,使得Python可以进行文件操作、进程管理、环境变量读取等系统级操作。 OS库中包含了大量的文件和目…

    编程 2025-04-25
  • Java BigDecimal 精度详解

    一、基础概念 Java BigDecimal 是一个用于高精度计算的类。普通的 double 或 float 类型只能精确表示有限的数字,而对于需要高精度计算的场景,BigDeci…

    编程 2025-04-25
  • git config user.name的详解

    一、为什么要使用git config user.name? git是一个非常流行的分布式版本控制系统,很多程序员都会用到它。在使用git commit提交代码时,需要记录commi…

    编程 2025-04-25

发表回复

登录后才能评论