• 数据结构与算法(位运算)


    位运算

    内存中的数据,最终的存储方式都是二进制,位运算就是对整数在内存的二进制位进行操作。

    按位与 &

    两个整数进行按位与运算,相同二进制位的数字如果都是是,则结果为1,有一个为0,则结果为0

    下面是 3 & 7 的计算过程

    二进制                整数

    0  1  1                   3

    1  1  1                   7

    0  1  1                   3(结果)

    3 & 7 = 3

    按位或 |

    两个整数进行按位或运算,相同二进制位的数字如果有一个为1,则结果为1,都为0,则结果为0

    下面是 5 | 8 的计算过程

    二进制                整数

    0  1  0  1               5

    1  0  0  0               8

    1  1  0  1              13(结果)

    5 | 8 = 13

    左移 <<

    二进制向左移动n位,在后面添加n个0

    下面的 3 << 1 的计算过程

    二进制                整数

          1  1                 3

      1  1  0                 6

    3<<1 = 6

    练习:一组数,内容为 3,9,19,20 ,请用一个整数来表示这四个数

    var value = 0
    value = value | 1<<3
    value = value | 1<<9
    value = value | 1<<19
    value = value | 1<<20
    console.log(value)

    程序输出结果为:1573384

    bitmap

    新的实现方式

    经过前面一系列的分析和位运算学习,现在我们要重新设计一个类,实现 addMember 和 isExist 方法,用更快的速度,更少的内存

    • 数据范围是0~100,那么只需要4个整数就可以表示 4 * 32 个数的存在与否(如果用普通的数组方法,需要数组中有100个数来表示0-100的存在与否),创建一个大小为4的数组
    • 执行addMember时,先用 member/32,确定member在数组里的索引(arr_index),然后用 member%32,确定在整数的哪个二进制位进行操作(bit_index),最后执行 bit_arr[arr_index] = bit_arr[arr_index] | 1<<bit_index
    • 执行isExist时,先用 member/32,确定member在数组里的索引(arr_index),然后用 member%32,确定在整数的哪个二进制位进行操作(bit_index),最后执行 bit_arr[arr_index] & 1<<bit_index ,如果结果不为 0 ,就说明 member存在
    function BitMap(size){
      var bit_arr = new Array(size)
      for(var i=0; i<bit_arr.length; i++){
        bit_arr[i] = 0
      }
    
      this.addMember = function(member){
        // 决定在数组中的索引
        var arr_index = Math.floor(member/32) 
        // 决定在整数的32个bit位的哪一位上
        var bit_index = member%32 
        bit_arr[arr_index] = bit_arr[arr_index] | 1<<bit_index
      }
    
      this.isExist = function(member){
        // 决定在数组中的索引
        var arr_index = Math.floor(member/32) 
        // 决定在整数的32个bit位的哪一位上
        var bit_index = member%32 
    
        var value = bit_arr[arr_index] & 1<<bit_index
        if(value !== 0){
          return true
        }
        return false
      }
    }

    概念

    这种数据结构基于位做映射,能够用很少的内存存储数据,和数组不同,它只能存储表示某个数是否存在,可以用于大数据去重,大数据排序,两个集合取交集。

    BitMap在处理大数据时才有优势,而且要求数据集紧凑,如果要处理的数只有3个:1,1000,100000,那么空间利用率太低了,最大的值决定了BitMap要用多少内存。

    大数据排序

    有多达10亿个无序整数,已知最大值为15亿,请对这10亿个数进行排序。(BitMap做排序有个前提,就是数据是不能重复的,如果有重复的就做不成了)

    传统排序算法都不可能解决这个排序问题,即便内存允许,其计算时间也是漫长的,如果使用BitMap就极为简单。

    BitMap存储最大值为15亿的集合,只需要180M 的空间,空间使用完全可以接受,至于速度,存储和比较过程中的位运算速度都非常快,第一次遍历,将10亿个数都放入到BitMap中,第二次,从0到15亿进行遍历,如果在BitMap,则输出该数值,这样经过两次遍历,就可以将如此多的数据排序。

    为了演示方便,只用一个很小的数组,[0, 6, 88, 7, 73, 34, 10, 99, 22],已知数组最大值是 99 ,利用BitMap排序的算法如下

    var arr = [0, 6, 88, 7, 73, 34, 10, 99, 22]
    var sort_arr = []
    
    var bit_map = new BitMap(4)
    for(var i=0; i<arr.length; i++){
      bit_map.addMember(arr[i])
    }
    
    for(var i=0; i<=99; i++){
      if(bit_map.isExist(i)){
        sort_arr.push(i)
      }
    }
    console.log(sort_arr)

    输出结果:[ 0, 6, 7, 10, 22, 34, 73, 88, 99 ]

    布隆过滤器

    前面所讲的BitMap的确很厉害,可以,却有着很强的局限性,BitMap只能用来处理整数,无法处理字符串,假设让你写一个强大的爬虫,每天爬取数以亿计的网页,那么你就需要一种数据结构,能够存储你已经爬取过的 url ,这样,才不至于重复爬取。

    你可能会想到使用hash函数对url进行处理,转成整数,这样,似乎又可以使用 BitMap 了,但这样还是会有问题。假设BitMap能够映射的最大值是 M ,一个url的hash值需要对M求模,这样,就会产生冲突,而且随着存储数据的增多,冲突率会越来越大。

    布隆过滤器的思想非常简单,其基本思路和BitMap是一样的,可以把布隆过滤器看做是 BitMap的扩展。为了解决冲突率,布隆过滤器要求使用k个 hash函数,新增一个 key时,把 key散列成 k 个整数,然后在数组中将这 k 个整数所对应的二进制位设置为1,判断某个key是否存在时,还是使用 k 个hash函数对key进行散列,得到k个整数,如果这k个整数所对应的二进制位都是1,就说明这个key存在,否则,这个key不存在。

    对于一个布隆过滤器,有两个参数需要设置,一个是预估的最多存放的数据的数量,一个是可以接受的冲突率。

    hash函数

    哈希函数就是将某一个不定长的对象映射为另一个定长的对象,如果你对这个概念感到困惑,你就换一个理解方法,你给hash函数传入一个字符串,它返回一个整数。为了实现一个布隆过滤器,我们需要一个好的 hash函数,计算快,冲突又少

  • 相关阅读:
    几个新角色:数据科学家、数据分析师、数据(算法)工程师
    人类投资经理再也无法击败电脑的时代终将到来了...
    Action Results in Web API 2
    Multiple actions were found that match the request in Web Api
    Routing in ASP.NET Web API
    how to create an asp.net web api project in visual studio 2017
    网站漏洞扫描工具
    How does asp.net web api work?
    asp.net web api history and how does it work?
    What is the difference between a web API and a web service?
  • 原文地址:https://www.cnblogs.com/haishen/p/11881935.html
Copyright © 2020-2023  润新知