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

yizhihongxing

数据结构之位图(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日

相关文章

  • c语言实现单链表算法示例分享

    下面是详细的攻略。 C语言实现单链表算法示例分享 什么是单链表 单链表是一种数据结构,它由一个个节点组成,每个节点包含两个部分:一个是数据部分,另一个是指针部分,指针部分指向下一个节点的位置。单链表的节点是动态分配的,可以随时插入、删除,是一种非常灵活的数据结构。 为什么要使用单链表 在进行一些操作时,数组或者普通的指针会遇到很多麻烦。比如在删除数组元素时,…

    数据结构 2023年5月17日
    00
  • 集合框架及背后的数据结构

    集合框架及背后的数据结构 集合框架是Java编程语言中的一组接口和实现类,用于存储数据的集合。集合框架中提供了许多不同类型的集合,包括List、Set、Map等。背后的数据结构是实现集合框架的关键,不同的数据结构适用于不同的集合类型和场景。 集合框架中的接口和实现类 Java中的集合框架定义了一些接口以及这些接口的实现类,在使用Java集合的时候,主要是使用…

    数据结构 2023年5月17日
    00
  • C语言 数据结构链表的实例(十九种操作)

    C语言 数据结构链表的实例(十九种操作)攻略 简介 链表是一种动态数据结构,以链式存储方式让任意节点之间相互连接,链表中的每个节点包含两个部分:数据域和指针域,数据域存储节点的数据,指针域存储下一个节点的地址。链表的优点是可以动态地分配内存,其缺点是查询效率较低。 本攻略将介绍19种链表操作,其中包括创建链表、添加节点、删除节点、查找节点以及遍历链表等操作。…

    数据结构 2023年5月17日
    00
  • Java实现链表数据结构的方法

    Java实现链表数据结构的方法可以分为以下步骤: 定义链表节点类Node 首先,在Java中实现链表数据结构,需要定义一个链表节点类,称为Node。Node类中包含两个重要属性: 数据域data,用于存储每个节点的数据信息。 指针域next,用于存储下一个节点的引用。 代码示例: public class Node { public int data; //…

    数据结构 2023年5月17日
    00
  • C++ 数据结构之布隆过滤器

    C++ 数据结构之布隆过滤器 简介 布隆过滤器是一种用于快速判断一个元素是否存在于一个集合中的数据结构。它的空间效率和查询效率都比较高,在某些场景下,它可以代替传统的哈希表。 原理 布隆过滤器的基本原理是:将一个元素映射为多个位数组中的位置。在插入元素时,将这些位置上的值设置为1;在查询元素时,如果这些位置上的值都为1,则认为元素存在于集合中;否则认为元素不…

    数据结构 2023年5月17日
    00
  • java 数据结构单链表的实现

    Java中实现单链表数据结构通常需要以下几个步骤: 1. 定义节点类 首先需要定义一个节点类,用于表示链表中的一个节点。每个节点包含两个属性:data表示节点的数据,next表示节点的下一个节点。这两个属性都需要定义为public,以便后续操作的访问。 public class Node { public int data; public Node next…

    数据结构 2023年5月17日
    00
  • Halcon软件安装与界面简介

      1. 下载Halcon17版本到到本地 2. 双击安装包后 3. 步骤如下     界面分为四大块 1.    Halcon的五个助手 1)    图像采集助手:与相机连接,设定相机参数,采集图像 2)    标定助手:九点标定或是其它的标定,生成标定文件及内参外参,可以将像素单位转换为长度单位 3)    模板匹配助手:画取你想寻找的图像,设定参数,可…

    算法与数据结构 2023年4月19日
    00
  • JavaScript 数据结构之散列表的创建(2)

    下面是详细讲解“JavaScript 数据结构之散列表的创建(2)”的完整攻略。 散列表(哈希表) 散列表是一种数据结构,使用哈希函数将键映射到索引。散列表可以在常量时间 O(1) 中进行插入、删除和查找操作,但也具有碰撞冲突问题。 碰撞冲突问题 在散列表中,当两个不同的键通过哈希函数映射到了同一个索引位置时,就会发生碰撞冲突问题。解决碰撞冲突问题的方法有很…

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