zoukankan      html  css  js  c++  java
  • 布隆过滤器(Bloom Filter)详解

    一.作用:

    判断一个元素是否存在一个集合中

    二.基本原理通俗:

    当一个元素被加入集合时,通过K个Hash函数将这个元素映射成一个一维的布尔型的数组中的K个点,把它们置为1。检索时,我们只要看看这些点是不是都是1就(大约)知道集合中有没有它了:如果这些点有任何一个0,则被检元素一定不在;如果都是1,则被检元素很可能在。这就是布隆过滤器的基本思想。

    三.算法原理详细:

    1. n个要添加的元素
    2. k个hash函数
    3. m位的空的bitArray
    4. 添加一个元素key时,用k个hash函数计算出k个散列值,并把bitArray对应的比特位置为1
    5. 判断一个元素key是否存在时,用k个hash函数计算出k个散列值,并查询bitArray中对应的比特位;如果至少有一位不为1,则一定不在集合中;如果全部都为1,则认为在集合中(存在误判)

    四.优缺点

    优点:

    新增,查询速度足够快,内存小,代码简单

    缺点:

    有一定误判率且随数据增加而增加; 不支持删除

    五.简单代码实现

    package scala02
    
    import scala.collection.mutable.ArrayBuffer
    import scala.math.abs
    import scala.util.hashing.MurmurHash3
    
     object BloomFilter {
    
       private val BYTE_SIZE: Int = 8
       private var m: Int = _   //m 为要存的比特数组长度
       private var k: Int = _       //k 为哈希函数的个数
       private var bitmapCharArray: Array[Char] = _  
       private var seedArray: Array[Int] = _
    
    
       /**
         * 生成空的bitArray
         * @param m
         * @return
         */
      private def generateEmptyBitmap(m:Int): Array[Char] ={
        val charNum = (m.toDouble/BYTE_SIZE).ceil.toInt //ceil 不小于该浮点数的最小整数, (2.1).ceil则为3.0
        val charArrayBuffer = ArrayBuffer.empty[Char]
        val char=0x00.toChar
        for (elem <- 0 until charNum ) {//0 until len  或者 0 to len-1
          charArrayBuffer.append(char)
        }
        charArrayBuffer.toArray
    
      }
    
       /**
         * 判断字符串是否可能存在于过滤器中
         *
         * @param str
         * @return
         */
       def exists(str: String): Boolean = {
         var flag = true
         var s = 0
         while (s < k) {
           val pos = hash(str, seedArray(s))
           if (!getBit(pos)) {
             flag = false
             s = k
           }
           s = s + 1
         }
         flag
       }
    
    
       /**
         * 将字符串添加到过滤器中
         *
         * @param str
         */
       def put(str: String) = {
         seedArray.foreach(seed => {
           val pos = hash(str, seed)
           setBit(pos)
         })
       }
    
       /**
         * 将bitmap的第pos个bit置为1
         *
         * @param pos
         */
       private def setBit(pos: Int): Unit = {
         val charPos = getCharPos(pos)
         val char = bitmapCharArray(charPos)
         val bitPos = pos - charPos * BYTE_SIZE
         val byte = char.toByte
         val mask = 0x01 << bitPos
         val or = byte | mask
         bitmapCharArray(charPos) = or.toChar
       }
       
    
    
       /**
         * 基于MurmurHash3算法计算字符串的hash值
         *
         * @param str
         * @param seed hash种子
         * @return 取值范围 0 ~ m-1
         */
       private def hash(str: String, seed: Int): Int = {
         abs(MurmurHash3.stringHash(str, seed)) % m
       }
    
       /**
         * 读取bitmap的第pos个bit
         *
         * @param pos
         */
       private def getBit(pos: Int): Boolean = {
         val charPos = getCharPos(pos)
         val char = bitmapCharArray(charPos)
         val bitPos = pos - charPos * BYTE_SIZE
         val byte = char.toByte
         val mask = 0x01 << bitPos
         val and = byte & mask
         if (0 == and) false else true
       }
    
       /**
         * 获取第pos个bit对应的char的位置(从0开始编号)
         *
         * @param pos
         * @return 0 ~ m/BYTE_SIZE-1
         */
       private def getCharPos(pos: Int): Int = {
         (pos.toDouble / BYTE_SIZE).toInt
       }
    
       /**
         * 判断n是否为质数
         *
         * @param n
         * @return
         */
       private def isPrime(n: Int) = {
         var flag = true
         for (i <- 2 to n - 1) {
           if (n % i == 0) flag = false
         }
         flag
       }
       
    
    }
    
    

    六.参考链接

    布隆过滤器原理及数学推导

    https://www.cnblogs.com/allensun/archive/2011/02/16/1956532.html

  • 相关阅读:
    SCU3033 Destroying a Painting(最小费用最大流)
    HDU4859 海岸线(最小割)
    ZOJ3228 Searching the String(AC自动机)
    HUST1024 dance party(最大流)
    SGU438 The Glorious Karlutka River =)(最大流)
    SPOJ839 Optimal Marks(最小割)
    BZOJ1086 [SCOI2005]王室联邦(树分块)
    SCU3109 Space flight(最大权闭合子图)
    HDU3138 Coconuts(最小割)
    ZOJ2539 Energy Minimization(最小割)
  • 原文地址:https://www.cnblogs.com/ShyPeanut/p/13935358.html
Copyright © 2011-2022 走看看