数据结构---位图算法

news2024/11/16 19:48:02

位图算法

  • 将数据存储到位图中
  • 查询数据是否在位图中
  • JAVA代码
  • 问题扩展

这里所说的位图并不是像素图片的位图,而是内存中连续的二进制位(bit)所组成的数据结构, 该算法主要用于对大量整数做去重和查询操作。

		System.out.println(1L <<0);
        System.out.println(1L <<1);
        System.out.println(1L <<2);
        System.out.println(1L <<3);
        System.out.println(1L <<4);
        System.out.println(1L <<5);
        System.out.println(1L <<6);
        System.out.println(1L <<64);
        System.out.println(1L <<65);
        System.out.println(1L <<67);

在这里插入图片描述
在这里插入图片描述

将数据存储到位图中

就是将Bitmap的对应位置设为1

  1. 定位到long[]数组中的对应的元素。
  2. 通过与运算修改long元素的值。
    /**
     * 定位Bitmap某一位所对应的word(long[] 类型)
     * @param bitIndex    位图的第bitIndex
     * @return
     */
    private int getWordIndex(int bitIndex){
        ///右移6位,相当于除以64
        //每一个word是一个long类型元素,对应一个64位二进制数据
        return bitIndex>>6;
    }

    /**
     * 把Bitmap某一位设置为true
     * @param bitIndex  位图的第bitIndex位
     */
    public void setBit(int bitIndex){
        if(bitIndex<0||bitIndex>size-1){
            throw new IndexOutOfBoundsException("超过bitmap的有效范围");
        }
        int wordIndex = getWordIndex(bitIndex);
        words[wordIndex]=words[wordIndex]|(1L<<bitIndex);
    }

在这里插入图片描述

查询数据是否在位图中

  1. 定位到long[]数组中的对应的元素。
  2. 判断long元素的对应位置的二进制位是否为1。
/**
     * 定位Bitmap某一位所对应的word(long[] 类型)
     * @param bitIndex    位图的第bitIndex
     * @return
     */
    private int getWordIndex(int bitIndex){
        ///右移6位,相当于除以64
        //每一个word是一个long类型元素,对应一个64位二进制数据
        return bitIndex>>6;
    }

/**
     * 判断Bitmap某一位的状态
     * @param bitIndex 位图的第bitIndex位
     * @return
     */
    public boolean getBit(int bitIndex){
        if(bitIndex<0||bitIndex>size-1){
            throw new IndexOutOfBoundsException("超过bitmap的有效范围");
        }
        //bitIndex转words数组的下标
        int wordIndex = getWordIndex(bitIndex);
        return (words[wordIndex]&(1L<<bitIndex))!=0;
    }

在这里插入图片描述

如果存在,则与运算的结果非0,返回True
否则结果为0,返回false

JAVA代码

public class MyBitmap {
    // 每一个word是一个long类型元素,对应一个64位二进制数据
    private long[] words;
    //Bitmap的位数大小
    private int size;

    public MyBitmap(int size) {
        this.size = size;
        //把Bitmap某一位所对应的word,初始化long[] words数组
        this.words = new long[getWordIndex(size-1)+1];
    }

    /**
     * 定位Bitmap某一位所对应的word(long[] 类型)
     * @param bitIndex    位图的第bitIndex
     * @return
     */
    private int getWordIndex(int bitIndex){
        ///右移6位,相当于除以64
        //每一个word是一个long类型元素,对应一个64位二进制数据
        return bitIndex>>6;
    }

    /**
     * 把Bitmap某一位设置为true
     * @param bitIndex  位图的第bitIndex位
     */
    public void setBit(int bitIndex){
        if(bitIndex<0||bitIndex>size-1){
            throw new IndexOutOfBoundsException("超过bitmap的有效范围");
        }
        int wordIndex = getWordIndex(bitIndex);
        words[wordIndex]=words[wordIndex]|(1L<<bitIndex);
    }

    /**
     * 判断Bitmap某一位的状态
     * @param bitIndex 位图的第bitIndex位
     * @return
     */
    public boolean getBit(int bitIndex){
        if(bitIndex<0||bitIndex>size-1){
            throw new IndexOutOfBoundsException("超过bitmap的有效范围");
        }
        //bitIndex转words数组的下标
        int wordIndex = getWordIndex(bitIndex);
        return (words[wordIndex]&(1L<<bitIndex))!=0;
    }

}

测试类如下:

public class testMyBitmap {
    public static void main(String[] args) {
        MyBitmap bitmap = new MyBitmap(128);
        bitmap.setBit(126);
        bitmap.setBit(75);
        System.out.println(bitmap.getBit(126));
        System.out.println(bitmap.getBit(78));

    }

}

在这里插入图片描述

查找的时间复杂度为O(1)
存储数据的空间复杂度较之前减少了1/32

问题扩展

给定 40 亿个不重复的没排过序的 unsigned int 型整数,然后再给定一个数,如何快速判断这个数是否在这 40 亿个整数当中?

40 亿个不重复整数,我们用 40 亿个 bit 来表示,初始位均为 0,那么总共需要内存:4,000,000,000b≈512M。
我们读取这 40 亿个整数,将对应的 bit 设置为 1。接着读取要查询的数,查看相应位是否为 1,如果为 1 表示存在,如果为 0 表示不存在。

总结:判断数字是否存在、判断数字是否重复的问题,位图法是一种非常高效的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/113725.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

地质灾害安全监测预警解决方案

一、方案背景 我国地质和地理环境复杂&#xff0c;气候条件时空差异大&#xff0c;地质灾害种类多、分布广、危害大&#xff0c;是世界上地质灾害最严重的国家之一。地质灾害来源于自然和人为作用下对地质环境的灾难性后果&#xff0c;主要包括崩塌、滑坡、泥石流、地面塌陷和…

RV1126笔记十六:吸烟行为检测及部署<三>

若该文为原创文章,转载请注明原文出处。 训练并测试(windows) 一、yolov5安装 1、下载rk优化后的yolov5 git clone https://github.com/airockchip/yolov5.git 下载后,我是放到E:\miniconda3\envs目录下,miniconda3是安装miniconda的目录。可以放到其他地方,后续操作需要…

语音处理的算法和方法研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Python pandas库|任凭弱水三千,我只取一瓢饮(7)

上一篇链接&#xff1a; Python pandas库&#xff5c;任凭弱水三千&#xff0c;我只取一瓢饮&#xff08;6&#xff09;_Hann Yang的博客-CSDN博客 to_系列函数&#xff1a;22个 &#xff08;12~22&#xff09; Function12 to_numpy(self, dtype: NpDtype | None None, co…

《网线制作》

前言&#xff1a; 随着计算机的快速发展&#xff0c; 现代 社会人们已经离不开网络&#xff0c;网络拉近了人们的距离&#xff0c;给人们提供了一个无需面对面就能够进行交流的平台&#xff0c;如今&#xff0c;网络已经渗透到生活的方方面面&#xff0c;购物、聊天、谈工作等…

【图卷积网络和知识提取】

When Pansharpening Meets Graph Convolution Network and Knowledge Distillation &#xff08;当全色锐化遇到图卷积网络和知识提取时&#xff09; 空洞卷积(Dilated/Atrous Convolution) 在本文中&#xff0c;我们提出了一种新颖的用于全色锐化的图卷积网络&#xff08;gra…

7. 表现层数据封装

表现层数据封装[TOC](表现层数据封装)1. 表现层响应数据的问题2. 定义ResponseResults类封装响应结果3. 定义Code类封装响应码4. 表现层数据封装返回Result对象5.postman发送请求结果1. 表现层响应数据的问题 ​ 目前表现层增删改方法返回true或者false表示是否成功&#xff0…

Kubernetes网络自学系列 | 网络虚拟化基石:network namespace

素材来源&#xff1a;《Kubernetes网络权威指南》 一边学习一边整理内容&#xff0c;并与大家分享&#xff0c;侵权即删&#xff0c;谢谢支持&#xff01; 附上汇总贴&#xff1a;Kubernetes网络自学系列 | 汇总_COCOgsta的博客-CSDN博客 1.1 网络虚拟化基石&#xff1a;netw…

【Pandas入门教程】如何计算汇总统计数据

如何计算汇总统计数据 来源&#xff1a;Pandas官网&#xff1a;https://pandas.pydata.org/docs/getting_started/intro_tutorials/index.html 笔记托管&#xff1a;https://gitee.com/DingJiaxiong/machine-learning-study 文章目录如何计算汇总统计数据导包数据准备【1】如何…

【学习Seata1.6源码#03】TC 集群具有高可用架构的秘密

一、背景 TC 集群具有高可用架构&#xff0c;应用到集群是这样一个间接的关系&#xff1a;应用 -》事务分组 -》TC 集群&#xff0c;应用启动后所指定的事务分组不能变&#xff0c;可通过配置中心变更事务分组所属的 TC 集群&#xff0c;Seata 客户端监听到这个变更后&#xf…

TIA博途中进行积分运算的具体方法

TIA博途中进行积分运算的具体方法 如下图所示,积分是对给定函数曲线的面积进行数学计算。但是实际曲线往往没有明确的数学关系,而是随时间变化的模拟量。积分计算就是把所有由两个过程值与时间所围成的梯形区域面积相加,梯形面积等于两个过程值的平均值乘以时间间隔。 如下…

MAC 下编译调试 MySQL8.0 源码

MAC 下编译调试 MySQL8.0 源码 最近遇到几个关于 MySQL 死锁的问题&#xff0c;但是查看网上的资料发现并不能解决我遇到的问题&#xff0c;于是决定从源码寻找答案&#xff0c;所以在这里记录一下自己编译 MySQL 源码的过程。 环境配置如下&#xff1a; macOS Ventura 版本 1…

达势股份IPO前紧急叫停:年内已有多家公司急刹车,王怡为董事长

又一家准上市公司在IPO前紧急叫停。 近日&#xff0c;达美乐比萨&#xff08;Domino’s Pizza&#xff0c;NYSE:DPZ&#xff09;在中国的运营商——达势股份&#xff08;DPC Dash Ltd&#xff0c;HK:01405&#xff09;发布《延迟全球发售及退回香港公开发售的申请股款》&#…

箭头函数的使用

一、什么是箭头函数 从 ES6 开始支持箭头函数&#xff0c;它是一种新的函数表达方式&#xff0c;可以在某些情况下使函数的使用更加的简洁。 二、箭头函数的使用 1、单个参数的使用 例&#xff1a; var f v > v;// 等同于var f function (v) {return v;};2、如果箭头函…

upload-labs(writeup)

pass1 前端验证&#xff0c;使用bp抓包改后缀 pass2 验证MIME类型&#xff0c;使用bp抓包&#xff0c;更改Content-Type 即可 pass3 黑名单限制&#xff0c;可以上传 .php3 .php5 .pthml 等等后缀&#xff0c; 但是要在phpstydy配置文件中更改&#xff0c;&#xff08;我使…

网络编程 基于tcp/ip协议的C/S模型

1.socket编程的一些概念 socket作用&#xff1a;运行在计算机中的两个程序通过socket建立起一个通道&#xff0c;数据在通道中传输。socket提供了流(stream)&#xff0c;是基于TCP协议&#xff0c;是一个有序、可靠、双向字节流的通道&#xff0c;传输数据不会丢失、不会重复、…

C#中的String和StringBuilder

一&#xff1a;前言 String和StringBuilder都是引用类型 StringBuilder是可变的字符串&#xff0c;它不会创建当前字符串的新修改实例而是在现有字符串对象中进行修改 String是不可变字符串&#xff0c;一旦被初始化后就不能改变其内容&#xff0c;String值改变的过程其实是创…

如何自定义注解

在 Spring Boot 应用中&#xff0c;使用自定义注解时需要用到 AOP&#xff0c;因此引入 AOP 相关依赖&#xff1a; <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependenc…

Python办公自动化|批量生成请假条

大家好&#xff0c;我是毕加锁 本文就将基于一个真实的办公案例进行讲解如何提取Excel内容并创建Word&#xff0c;主要将涉及以下三个知识点 “ openpyxl 读取 Excel 文件 python-docx 写入 Word 文件 python-docx 各类样式的设计和调整 ”需求描述 你是公司的底层小虾米&…

2022年AIGC简单展望

2022 对于社会是不平凡的一年&#xff0c;而对于科技也同样是不平凡的一年。人们在社会中遭受着失意&#xff0c;却在科技中寻找希冀。对于一个命运共同体&#xff0c;它想着如何破除衰退&#xff0c;而同样对于一个活生生的个体或者家庭&#xff0c;他们也在摸索改变命运的机遇…