0

0

c++怎么实现一个位图(bitmap)_c++位操作实现高效数据标记

穿越時空

穿越時空

发布时间:2025-10-24 22:34:02

|

842人浏览过

|

来源于php中文网

原创

位图通过位操作用少量内存高效标记大量整数状态,核心是使用std::vector按位存储,每个bit表示一个整数的存在与否,支持快速的set、clear、get操作,并可扩展优化如64位块、popcount统计等,适用于去重、排序、资源管理等场景。

c++怎么实现一个位图(bitmap)_c++位操作实现高效数据标记

在C++中实现一个位图(Bitmap),核心是用少量内存高效标记大量整数状态,比如记录某个整数是否出现过、某个资源是否被占用等。通过位操作直接管理二进制位,可以将空间消耗降低到传统布尔数组的1/8甚至更少。

基本原理与设计思路

位图本质是一个大数组,每个比特(bit)代表一个数据项的状态:0表示未标记,1表示已标记。假设要管理从0到N-1的整数,就需要至少N个bit的空间。

例如,管理0~31的整数,只需要一个unsigned int(通常32位)即可;管理0~9999,则需要约10000 / 32 ≈ 313个unsigned int

关键点:
  • 使用std::vector或裸指针管理位存储块
  • 通过位运算实现单个bit的设置、清除、查询
  • 支持快速清零、填充、遍历等操作

位操作基础:如何定位和修改某一位

给定一个整数index,找出它在哪个整型单元中,以及在该单元中的第几位。

立即学习C++免费学习笔记(深入)”;

  • 所在块索引: index / 32 或等价于 index >> 5
  • 位偏移: index % 32 或等价于 index & 0x1F
  • 设置位: bits[block] |= (1U
  • 清除位: bits[block] &= ~(1U
  • 查询位: (bits[block] >> offset) & 1

这些位运算非常高效,编译器通常会优化成CPU原生指令。

讯飞绘文
讯飞绘文

讯飞绘文:免费AI写作/AI生成文章

下载

简易位图类实现示例

下面是一个轻量级、可复用的Bitmap实现:

class Bitmap {
private:
    std::vector data;
    int size; // 总共管理多少位

public:
    explicit Bitmap(int n) : size(n) {
        data.resize((n + 31) / 32, 0);
    }

    void set(int index) {
        if (index < 0 || index >= size) return;
        int block = index >> 5;
        int offset = index & 0x1F;
        data[block] |= (1U << offset);
    }

    void clear(int index) {
        if (index < 0 || index >= size) return;
        int block = index >> 5;
        int offset = index & 0x1F;
        data[block] &= ~(1U << offset);
    }

    bool get(int index) const {
        if (index < 0 || index >= size) return false;
        int block = index >> 5;
        int offset = index & 0x1F;
        return (data[block] >> offset) & 1;
    }

    void reset() {
        std::fill(data.begin(), data.end(), 0);
    }
};

这个实现简洁且高效,适合嵌入式、算法题或高性能场景。

应用场景与优化建议

位图常见用途包括:

  • 去重统计:如布隆过滤器底层结构
  • 内存分配器:标记页是否空闲
  • 排序加速:对小范围整数进行O(n)排序(计数排序变种)
  • 状态标记:任务调度中标记任务完成状态
优化方向:
  • 使用uint64_t代替unsigned int提升吞吐(64位系统)
  • 添加count()方法,用__builtin_popcount加速统计1的数量
  • 支持原子操作版本用于多线程环境
  • 动态扩容(类似std::vector)以支持不确定范围

基本上就这些。位图结合位操作,是C++中实现高效数据标记的经典手段,简单但威力强大。

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

193

2023.11.20

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

314

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

524

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

49

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

190

2025.08.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

473

2023.08.10

Python 多线程与异步编程实战
Python 多线程与异步编程实战

本专题系统讲解 Python 多线程与异步编程的核心概念与实战技巧,包括 threading 模块基础、线程同步机制、GIL 原理、asyncio 异步任务管理、协程与事件循环、任务调度与异常处理。通过实战示例,帮助学习者掌握 如何构建高性能、多任务并发的 Python 应用。

135

2025.12.24

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

390

2023.08.14

漫画合集pdf网盘入口_漫画解说合集一口气看完
漫画合集pdf网盘入口_漫画解说合集一口气看完

精选高人气漫画合集PDF,一站式网盘入口直达!深度漫画解说整合,一口气看完经典与新作,剧情梳理清晰,省时省力,追漫党必看合集。

3

2026.01.04

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 5.9万人学习

C 教程
C 教程

共75课时 | 3.8万人学习

C++教程
C++教程

共115课时 | 11万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号