数据结构之位图(bitmap)详解

数据结构之位图(bitmap)详解

什么是位图?

位图,又称为比特图、Bitmap,是一种非常常用的数据结构。它是一种特殊的数组,只能存储0或1,可以用来表示一些二元状态,如二进制码、字符集、颜色等信息。在数据挖掘、工程设计、网络安全等领域都有广泛的应用。

位图的原理

位图的原理是用数据的位来表示某个元素对应的值。如果对应位为1,则代表该元素存在,否则代表该元素不存在。因此,位图可以用1/0来表示元素的状态。

位图的优点

  1. 节省内存空间:位图比较节省内存空间,因为位图中每个位置只用来存储0或1,而且每个位置只需要1bit的存储空间,比如用位图来存储10亿个数,只需要占用大约125MB的内存空间,而且操作速度会更快。

  2. 操作便捷:由于位图只用0 1来表示元素状态,进行逻辑运算的速度也更快,如交集、并集、补集等。

位图的缺点

  1. 位图只适用于数据的状态才是0、1这样的二元状态,并且数据范围较小时,才更适合使用位图。

  2. 在海量数据的情况下,可能会导致位图占用大量的内存空间。

位图的应用

  1. 用于数据的去重工作:当需要进行去重操作时,可以利用位图来去掉重复数据。

示例:假设有一组数据,范围在1到100亿之间,而且这些数据中存在大量的重复数据,使用位图方法可以快速去重,具体实现过程如下:

    // 生成一个100亿位的位图,所有位初始值均为0
    uint64_t* bitmap = new uint64_t[0b1110111001100001001000000000000];

    // 读取数据进行处理(以下代码仅为示例代码,并不一定是最优代码)
    ifstream fs("data.txt");
    uint64_t num;
    while(fs >> num){
        // 通过num的值,确定它在bitmap中的位置,并将对应位置的值设为1
        bitmap[num/64] |= 1ULL<<(num%64);
    }

    // 去重后的数据保存在result数组中
    uint64_t result[1000000];
    int n = 0;
    for(int i=0; i<0b1110111001100001001000000000000; i++){
        uint64_t b = bitmap[i];
        if(b == 0) continue;
        // 逐位判断bitmap中的二进制位是否为1
        for(int j=0; j<64; j++){
            if(b&(1ULL<<j)){
                // 通过位运算还原出对应的数字
                result[n++] = i*64+j;
            }
        }
    }

    // 打印去重后的结果
    for(int i=0; i<n; i++){
        cout << result[i] << " ";
    }
  1. 判断数据是否存在:通过位图来标识数据是否存在。

示例:假设有一组GPS坐标数据,其中有一些数据点已知为非法数据点,可以通过位图来判断某个数据点是否为非法点。

    // 生成一个2^32位大小的位图,所有位初始值均为0
    uint32_t* bitmap = new uint32_t[1ULL<<(32-5)];

    // 假设非法数据点为以下几个
    uint32_t illegal_points[] = {0x01234567, 0x89ABCDEF, 0xDEADBEEF};

    // 将非法数据点对应的位置的值设为1
    for(auto p : illegal_points){
        bitmap[p>>5] |= 1<<(p&0x1f);
    }

    // 判断某个数据点是否为非法点
    uint32_t point = 0x12345678;
    bool is_illegal = bitmap[point>>5]&(1<<(point&0x1f));
    cout << (is_illegal ? "illegal" : "legal") << endl;

总结

位图是一种高效的数据结构,可以用来实现一些二元状态的操作,如重复数据的去重、判断元素是否存在等。它优点是节省内存空间、操作便捷;缺点是只适用于二元状态的数据,并且对于数据范围较大时可能会消耗较多内存空间。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:数据结构之位图(bitmap)详解 - Python技术站

(0)
上一篇 2023年5月17日
下一篇 2023年5月17日

相关文章

  • GPS北斗卫星时间同步系统助力电力自动化网络系统

    GPS北斗卫星时间同步系统助力电力自动化网络系统 GPS北斗卫星时间同步系统助力电力自动化网络系统 京准电子官微——ahjzsz 前言 近几年来,随着电力自动化水平的提高,在电力中计算机监控系统、微机保护装置、微机故障录波装置以及各类数据管理机得到了广泛的应用,而这些自动装置的配合工作需要有一个精确统一的时间。当电力系统发生故障时,既可实现全站各系统在统一时…

    算法与数据结构 2023年5月8日
    00
  • C++20中的结构化绑定类型示例详解

    ” C++20中的结构化绑定类型示例详解 ” 具体攻略如下: 什么是结构化绑定类型? 结构化绑定类型是C++17中的新特性,它可以让我们将一个复杂类型的元素绑定到某个变量上,从而更方便地使用这些元素。 C++20还进一步扩展了结构化绑定类型的功能,可以通过给用于引用的名字声明类型来进行显式类型的绑定。 结构化绑定类型的基本用法 下面的例子展示了如何使用结构化…

    数据结构 2023年5月17日
    00
  • Java面试题冲刺第十九天–数据库(4)

    本篇攻略是针对Java数据库相关面试题的,为了方便浏览,我将其分为以下几个部分: 1. 数据库连接池 在Java开发中,我们使用JDBC连接数据库进行数据操作时,为了提高数据库访问性能,通常会使用数据库连接池技术。常见的数据库连接池有:C3P0、Druid、HikariCP等。 C3P0 C3P0是一个开源的数据库连接池,可以设置最大连接数、最小连接数、最大…

    数据结构 2023年5月17日
    00
  • C语言数据结构 栈的基础操作

    C语言数据结构 栈的基础操作 1. 栈的基本概念 栈(Stack)是一种基于LIFO(后进先出)原理的数据结构,类似于一组盘子,只能在盘子的顶部进行操作。每次从顶部添加或移除盘子。 栈具有两个基本操作:入栈(push)和出栈(pop)。当添加一个元素时,我们称其为“push”,当移除一个元素时,我们称其为“pop”。 2. 栈的实现 栈可以使用数组或链表来实…

    数据结构 2023年5月17日
    00
  • 数据结构 数组顺序存储详细介绍

    数据结构数组顺序存储详细介绍 什么是数组顺序存储? 数组是最基本的数据结构之一,在计算机程序中使用广泛。在数组中,存储的元素类型相同且占用相同的内存空间,可以通过下标进行快速访问和修改。数组可以使用不同的方法来存储在内存中,其中最简单的方法是数组顺序存储。 数组顺序存储是指将元素按照顺序依次存储在内存中的一块连续地址中,可以方便地进行随机访问。这种方式与链式…

    数据结构 2023年5月17日
    00
  • C语言顺序表的基本结构与实现思路详解

    C语言顺序表的基本结构与实现思路详解 什么是顺序表 顺序表,顾名思义,就是使用连续的存储空间来存储数据元素的线性表。在顺序表中,每一个数据元素都占用一个连续的存储单元,这些存储单元在物理上连续存放,因此,顺序表实际上就是由一个存储数据元素的数组和记录该数组大小的变量组成的。 顺序表的基本结构 顺序表的定义 “`c #define MAXSIZE 100 /…

    数据结构 2023年5月17日
    00
  • 牛客小白月赛71

    A.猫猫与广告 题目: 分析: 只需考虑c * d的矩阵竖着摆和横着摆两种情况。本题提示了考虑两矩阵对应边平行的情况,实际上可以证明倘若能斜着放,那么一定可以横着放或竖着放,证明方式可已通过构造三角形来证明a* b的矩阵的长宽一定小于c * d矩阵的长宽。 code: #include <iostream> #include <cmath&…

    算法与数据结构 2023年4月25日
    00
  • 使用C语言构建基本的二叉树数据结构

    下面是使用C语言构建二叉树数据结构的步骤和示例: 1. 定义二叉树结构体类型 定义一个二叉树的结构体,包含节点值、左右子节点等信息: typedef struct TreeNode { int val; struct TreeNode* left; struct TreeNode* right; } TreeNode; 2. 实现创建二叉树的函数 实现一个函…

    数据结构 2023年5月17日
    00
合作推广
合作推广
分享本页
返回顶部