当前位置: 首页 > news >正文

位图详解.

1.位图概念

给40亿个不重复的无符号整数,没排过序。给一个无符号整数,如何快速判断一个数是否在这40亿个数中?

思考:

1.用哈希表?遍历一遍?时间复杂度O(N)

40亿个不重复无符号整数占多大内存?

10亿个字节大约是1个G

10亿个整数大约是4个G

40亿个整数大约是16个G

电脑的运行内存16个G,放不下


2.用快速排序+二分查找?时间复杂度 O(N*log2^N) + O(logN)

面临同样的问题,电脑的运行内存16个G,放不下

3.位图

数据是否在给定的整形数据中,结果是在或者不在,刚好是两种状态,那么可以使用一个二进制比
特位来代表数据是否存在的信息,如果二进制比特位为1,代表存在,为0代表不存在。
 

10个整数本应该存放40个字节,用到位图只需要3个字节

40亿个整数存放160亿个字节,用到位图只需要4 000 000 000 / 8 个字节

大约是4 000 000 000 / 8 / 1024 / 1024 = 476.837M(兆)

也就是说,我用476兆就能把40亿个数据表示出来,这就是位图的作用

2.适用场景 

海量数据,整数,数据无重复的场景。通常是用来判断某个数据存不存在的。

3.举个例子
 

package test;

import java.util.BitSet;

public class Test {
    public static void main(String[] args) {
        int[] array = {1, 2, 3, 10, 4, 18, 13, 15};
        BitSet bitSet = new BitSet();
        for (int i = 0; i < array.length; i++) {
            bitSet.set(array[i]);
        }
        System.out.println(bitSet.get(10));
        System.out.println(bitSet.get(45));
    }
}

 4.具体实现

package test;

import java.util.Arrays;

public class MyBitSet {
    public byte[] elem;
    public int usedSize;

    public MyBitSet() {
        this.elem = new byte[1];
    }

    public MyBitSet(int n) {
        this.elem = new byte[n / 8 + 1];
    }

    //设置某一位为一
    public void set(int val) {
        if (val < 0) {
            System.out.println("只能为无符号整数,不能为负数");
            throw new IndexOutOfBoundsException();
        }

        int arrayIndex = val / 8;
        if (arrayIndex > elem.length - 1) {
            elem = Arrays.copyOf(elem, arrayIndex + 1);
        }
        int bitIndex = val % 8;
        elem[arrayIndex] |= (1 << bitIndex);
        usedSize++;
    }

    public int getUsedSize() {
        return usedSize;
    }

    //判断当前位 是不是1
    public boolean get(int val) {
        if (val < 0) {
            System.out.println("只能为无符号整数,不能为负数");
            throw new IndexOutOfBoundsException();
        }
        int arrayIndex = val / 8;
        if (arrayIndex > elem.length - 1) {
            elem = Arrays.copyOf(elem, arrayIndex + 1);
        }
        int bitIndex = val % 8;

        if ((elem[arrayIndex] & (1 << bitIndex)) != 0) {
            return true;
        }
        return false;
    }

    //将对应位置 置位0
    public void reSet(int val) {
        if (val < 0) {
            System.out.println("只能为无符号整数,不能为负数");
            throw new IndexOutOfBoundsException();
        }
        int arrayIndex = val / 8;
        int bitIndex = val % 8;
        elem[arrayIndex] &= ~(1 << bitIndex);
        usedSize--;
    }

    public static void main(String[] args) {
        MyBitSet myBitSet = new MyBitSet(22);
        int[] array = {1, 3, 7, 4, 12, 16, 19, 13, 22, 18, 3};
        for (int i = 0; i < array.length; i++) {
            myBitSet.set(array[i]);
        }
        System.out.println(myBitSet.getUsedSize());
        System.out.println(myBitSet.get(7788));
        System.out.println(myBitSet.get(4));

        //排序 时间复杂度O(N)
        for (int i = 0; i < myBitSet.elem.length; i++) {
            for (int j = 0; j < 8; j++) {
                if ((myBitSet.elem[i] & (1 << j)) != 0) {
                    System.out.print((i * 8 + j) + " ");
                }
            }
        }
    }
}

相关文章:

  • 湖州做网站/seo搜索优化公司排名
  • 国土资源网站建设方案/站长seo
  • 网站版面设计/百度识图网页版在线使用
  • 福建坤辕建设工程有限公司网站/刷粉网站推广便宜
  • 网站做几个域名比较好/阻断艾滋病的药有哪些
  • 文山州住房建设网站/seo软件开发
  • 西瓜书-支持向量机
  • Minecraft 1.19.2 Forge模组开发 09.动画效果方块
  • 跑步热来袭!缤跃关注运动健康生活,跨界推出差异化酒店产品!
  • 如何解决错误 ModuleNotFoundError:No module named“matplotlib“
  • 欧盟森林砍伐法规和合规性:使用 Dimitra 技术解决森林砍伐问题
  • 生成模型(四):扩散模型(Diffusion Models)
  • VMware ESxi 服务器迁移【手动版】
  • 史上最简单易懂的TypeScript教程(更新中)
  • 用arduino从零开始做一个《儿童算术智能出题机》——NO.1硬件篇(MAX7219、矩阵键盘、GD3800D、3D打印)
  • 汉诺塔问题的时间复杂度
  • CSS -- CSS3中3D转换相关属性讲解(translate3d,rotate3d,perspective,transform-style)
  • 【第一周学习——认识 O(N*logN) 的排序[ 归并排序 、堆排序、快速排序 ]