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

 更新时间:2014年08月28日 10:14:21   投稿:junjie  
这篇文章主要介绍了数据结构之位图详解,本文讲解了位图的基本知识、位图的实现方法、位图的应用等内容,需要的朋友可以参考下

1.  概述

位图(bitmap)是一种非常常用的结构,在索引,数据压缩等方面有广泛应用。本文介绍了位图的实现方法及其应用场景。

2. 位图实现

(1)自己实现
在位图中,每个元素为“0”或“1”,表示其对应的元素不存在或者存在。

复制代码 代码如下:

#define INT_BITS sizeof(int)
 
#define SHIFT 5 // 2^5=32
 
#define MASK 0x1f // 2^5=32
 
#define MAX 1024*1024*1024 //max number
 
int bitmap[MAX / INT_BITS];
 
/*
 
* 设置第i位
 
* i >> SHIFT 相当于 i / (2 ^ SHIFT),
 
* i&MASK相当于mod操作 m mod n 运算
 
*/
 
void set(int i) {
 
bitmap[i >> SHIFT] |= 1 << (i & MASK);
 
}
 
//获取第i位
 
int test(int i) {
 
return bitmap[i >> SHIFT] & (1 << (i & MASK));
 
}
 
//清除第i位
 
int clear(int i) {
 
return bitmap[i >> SHIFT] & ~(1 << (i & MASK));
 
}

(2)函数库实现

C++的STL中有bitmap类,它提供了很多方法,详见:http://www.cplusplus.com/reference/stl/bitset/

3.  位图应用

3.1    枚举
(1)全组合
字符串全组合枚举(对于长度为n的字符串,组合方式有2^n种),如:abcdef,可以构造一个从字符串到二进制的映射关系,通过枚举二进制来进行全排序。

复制代码 代码如下:

null——> 000000
f——> 000001
e——> 000010
ef——> 000011
……
abcedf——> 111111

(2)哈米尔顿距离

枚举算法,复杂度是O(N^2),怎样降低复杂度呢?
如果是N 个二维的点,那么我们可以怎么用较快的方法求出

通过简单的数学变形,我们可以得到这样的数学公式:

通过观察,我们发现每一对相同元的符号必定相反,如:x_i-y_i,于是我们有了一个二进制思想的思路,那就是枚举这些二i维的点的x 轴y 轴前的正负号,这样就可以用一个0~3 的数的二进制形式来表示每个元素前面的正负号,1表示+号,0表示−号,如:2 表示的二进制位形式为10表示x_i-y_i。这样我们就可以通过2^2*N次记录下这些二元组的不同的符号的数值,对于每个二进制来表示的不同的式子只需记录下他们的值,这样我们只需求max_i 和min_i出这些相同的二进制表示的式子max_i –min_i,最后我们就可以解出ans=max{max_i-min_i}。

通过位图,算法时间复杂度可将为O(N)。

3.2   搜索

设计搜索剪枝时,需要保存已经搜索过的历史信息,有些情况下,可以使用位图减小历史信息数据所占空间。

3.3 压缩

(1)在2.5亿个整数中找出不重复的整数,注,内存不足以容纳这2.5亿个整数?

(2)腾讯面试题:给40亿个不重复的unsigned int的整数,没排过序的,然后再给一个数,如何快速判断这个数是否在那40亿个数当中?

4. 总结

Bitmap是一种非常简洁快速的数据结构,他能同使证存储空间和速度最优化(而不必空间换时间)。

5.  参考资料
(1)《C实现bitmap位图》:https://www.jb51.net/article/54438.htm
(2)武森《浅谈信息学竞赛中的“0”和“1”》

相关文章

  • C++ set的使用方法详解

    C++ set的使用方法详解

    这篇文章主要介绍了C++ set的使用方法详解的相关资料,希望通过本文能帮助到大家,让大家理解掌握set的使用方法,需要的朋友可以参考下
    2017-10-10
  • C++整数拼接技巧大揭秘

    C++整数拼接技巧大揭秘

    C++整数拼接技巧大揭秘,让你的代码更简洁高效!你是否还在为如何优雅地将整数拼接成字符串而烦恼?本指南将为你揭示C++中最实用、最酷炫的整数拼接技巧,助你提升编程技能,需要的朋友可以参考下
    2024-03-03
  • C语言中常见的六种动态内存错误总结

    C语言中常见的六种动态内存错误总结

    学习过C语言中的动态内存函数,例如【malloc】、【calloc】、【realloc】、【free】,那它们在使用的过程中会碰到哪些问题呢,本本文我们一起来探讨下,感兴趣的朋友跟着小编一起来看看吧
    2023-11-11
  • C++实现文件逐行读取与字符匹配的示例详解

    C++实现文件逐行读取与字符匹配的示例详解

    这篇文章主要为大家详细介绍了如何溧阳C++实现文件逐行读取与字符匹配的功能,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下
    2023-03-03
  • VC中控制台程序创建窗口的实例方法

    VC中控制台程序创建窗口的实例方法

    在本篇文章里小编给大家分享的是关于VC中控制台程序创建窗口的实例方法及相关代码内容,有需要的朋友学习下吧。
    2021-12-12
  • c++编写String类代码实例

    c++编写String类代码实例

    这篇文章主要介绍了c++编写String类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-04-04
  • 二叉树遍历 非递归 C++实现代码

    二叉树遍历 非递归 C++实现代码

    对于二叉树,有前序、中序以及后序三种遍历方法。因为树的定义本身就是递归定义,因此采用递归的方法去实现树的三种遍历不仅容易理解而且代码很简洁。而对于树的遍历若采用非递归的方法,就要采用栈去模拟实现
    2013-09-09
  • C 字符串数组排序的小例子

    C 字符串数组排序的小例子

    C 字符串数组排序的小例子,需要的朋友可以参考一下
    2013-03-03
  • 使用C语言打造通讯录管理系统和教学安排系统的代码示例

    使用C语言打造通讯录管理系统和教学安排系统的代码示例

    这篇文章主要介绍了使用C语言打造通讯录管理系统和教学安排系统的代码示例,利用C语言强大的数组和指针能够更加清晰地体现设计思路:D 需要的朋友可以参考下
    2016-06-06
  • 利用Qt实现获取计算机的硬件信息

    利用Qt实现获取计算机的硬件信息

    在开发时,常常会需要用到计算机的相关信息。利用这些信息,我们可以开发一些辅助模块。本文将利用Qt实现获取计算机的硬件信息,感兴趣的可以尝试一下
    2022-12-12

最新评论