【本文链接】

http://www.cnblogs.com/hellogiser/p/bitmap-vs-2bitmap.html

【题目】

在2.5亿个整数找出不重复的整数,内存不足以容纳着2.5亿个整数

【分析】

Bitmap就是用一个bit位来标记某个元素是否存在,而2Bitmap就是用两个bit为来标记某个元素的个数,00,01,10,11(分别表示0,1,2,3,0表示不存在,1表示存在1次,后面依次)。

整数可能是正数也可能是负数,首先只考虑正整数情况,采用2Bitmap方法,用00表示不存在,01表示出现1次,10表示出现2次及以上,此方法总共需要的内存2^31*2bit = 1Gb = 128MB(32位的正整数有2^31个,每个存储需要2bit,所以就是1Gb,换成字节就是128MB),这样内存就应该能够容纳了,最后在处理完所有的数后,只要输出对应位为01的数即可。如果这2.5亿个数里面既有正数又有负数那么就用两个2Bitmap分别存储正数和负数(取绝对值存储),零就随便放,所需要的内存是512MB。

【代码】

 C++ Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
 
/*
version: 1.0
author: hellogiser
blog: http://www.cnblogs.com/hellogiser
date: 2014/10/8
*/

#include "stdafx.h"
#include <iostream>
using namespace std;

class BitSet
{
public:
    BitSet (int range)
    {
        // [0,range)
        m_nRange = range;
        m_nLength = m_nRange / ;

bitset = new int[m_nLength];
        // init all with 0
; i < m_nLength; i++)
        {
            bitset[i] = ;
        }
    }

~BitSet()
    {
        delete []bitset;
    }

void Set(int number)
    {
        ;
        ;
        bitset[i] |= ( << j);
    }

int Get(int number)
    {
        ;
        ;
         << j)) >> j;
    }

void Output()
    {
        ; i < m_nRange; i++)
        {
            if (Get(i))
            {
                cout << i << " ";
            }
        }
        cout << endl;
    }
private:
    int *bitset;
    int m_nRange; // range of numbers
    int m_nLength; // len of array
};

class BitSet1
{
public:
    BitSet1 (int range)
    {
        // [0,range)
        //default value
;
        m_nWord =  / m_nBitWidth;

m_nRange = range;
        m_nLength = m_nRange / m_nWord + ;

bitset = new int[m_nLength];
        // init all with 0
; i < m_nLength; i++)
        {
            bitset[i] = ;
        }
    }

~BitSet1()
    {
        delete []bitset;
    }

void Set(int number)
    {
        int i = number / m_nWord;
        int j = number % m_nWord;
        bitset[i] |= ( << j);
    }

void Clear(int number)
    {
        int i = number / m_nWord;
        int j = number % m_nWord;
        bitset[i] &= ~( << j);
    }

int Get(int number)
    {
        // return count of number
        int i = number / m_nWord;
        int j = number % m_nWord;
         << j)) >> j;
    }

void Output()
    {
        ; i < m_nRange; i++)
        {
            if (Get(i))
            {
                cout << i << " ";
            }
        }
        cout << endl;
    }
private:
    int m_nBitWidth;// 1 2 3
    int m_nWord; // word = 32/BitWidth
    /*  1: 0,1
        2: 00,01,10,11
        3: 000,...111
    */

int *bitset;
    int m_nRange; // range of numbers
    int m_nLength; // len of array
};

class BitSet2
{
public:
    BitSet2 (int range)
    {
        // [0,range)
        //default value
;// 1,2,3
 / m_nBitWidth; //32, 16,8
 << m_nBitWidth; //1,3,7

m_nRange = range;
        m_nLength = m_nRange / m_nWord + ;

bitset = new int[m_nLength];
        // init all with 0
; i < m_nLength; i++)
        {
            bitset[i] = ;
        }
    }

~BitSet2()
    {
        delete []bitset;
    }

void Add(int number)
    {
        int count = Get(number);
        __Set(number, count + );
    }

void __Set(int number, int count)
    {
        )
            return;
        //clear first
        Clear(number);

// then set
        int i = number / m_nWord;
        int j = number % m_nWord;
        bitset[i] |= (( * j);
    }

void Clear(int number)
    {
        int i = number / m_nWord;
        int j = number % m_nWord;
        bitset[i] &= ~( * j));
    }

int Get(int number)
    {
        // return count of number
        int i = number / m_nWord;
        int j = number % m_nWord;
         * j);
    }

void Output()
    {
        ; i < m_nRange; i++)
        {
            if (Get(i))
            {
                cout << i << " ";
            }
        }
        cout << endl;
    }
private:
    int m_nBitWidth;// 1 2 3
    int m_nWord; // word = 32/BitWidth
    /*  1: 0,1
        2: 00,01,10,11
        3: 000,...111
    */
    int m_nMaxCount; // 1,11,111===>1,3,7

int *bitset;
    int m_nRange; // range of numbers
    int m_nLength; // len of array
};

void test_default1(int *a, int len, int range)
{
    cout << "===Bitset1===" << endl;
    BitSet1 bs1(range);
    ; i < len; i++)
    {
        bs1.Set(a[i]);
    }

; i < range; i++ )
    {
        cout << i << " count = " << bs1.Get(i) << endl;
    }
}

void test_case1()
{
    };
    ;
    test_default1(a, , range);
}

void test_default2(int *a, int len, int range)
{
    cout << "===Bitset2===" << endl;
    BitSet2 bs2(range);
    ; i < len; i++)
    {
        bs2.Add(a[i]);
    }

; i < range; i++ )
    {
        cout << i << " count = " << bs2.Get(i) << endl;
    }
}

void test_case2()
{
    };
    ;
    test_default2(a, , range);
}

int main()
{
    test_case1();
    test_case2();
    ;
}
/*
===Bitset1===
0 count = 0
1 count = 1
2 count = 1
3 count = 1
4 count = 1
5 count = 1
6 count = 0
7 count = 1
8 count = 1
9 count = 0
===Bitset2===
0 count = 0
1 count = 1
2 count = 2
3 count = 3
4 count = 3
5 count = 1
6 count = 0
7 count = 1
8 count = 1
9 count = 0
*/

【其它题目】

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

unsigned int 的取值范围是0到2^32-1。我们可以申请连续的2^32/8=512M的内存,用每一个bit对应一个unsigned int数字。首先将512M内存都初始化为0,然后每处理一个数字就将其对应的bit设置为1。当需要查询时,直接找到对应bit,看其值是0还是1即可。

2.有1到10w这10w个数,去除2个并打乱次序,如何找出那两个数?
申请10w个bit的空间,每个bit代表一个数字是否出现过。开始时将这10w个bit都初始化为0,表示所有数字都没有出现过。然后依次读入已经打乱循序的数字,并将对应的bit设为1。当处理完所有数字后,根据为0的bit得出没有出现的数字。

【参考】

http://blog.csdn.net/jirongzi_cs2011/article/details/9331003

http://www.cnblogs.com/pangxiaodong/archive/2011/08/14/2137748.html

http://blog.csdn.net/acceptedxukai/article/details/9025493

http://blog.csdn.net/zhulei632/article/details/6701868

Bitmap vs 2Bitmap的实现的更多相关文章

  1. Android canvas.save()与canvas.restore()的使用总结

    含义canvas.save(); 画布将当前的状态保存canvas.restore(); 画布取出原来所保存的状态使用 canvas.save();与canvas.restore();一般结合使用,. ...

  2. 大数据处理-bitmap是个神马东西

    1. Bit Map算法简介 所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空间方面,可以大大节省. 2. B ...

  3. 海量数据处理算法—Bit-Map

    原文:http://blog.csdn.net/hguisu/article/details/7880288 1. Bit Map算法简介 来自于<编程珠玑>.所谓的Bit-map就是用一 ...

  4. 3.bit-map

    适用范围:可进行数据的快速查找,判重,删除,一般来说数据范围是int的10倍以下 基本原理及要点:使用bit数组来表示某些元素是否存在,比如8位电话号码 扩展:bloom filter可以看做是对bi ...

  5. BitMap位图与海量数据的理解

    1. Bit Map算法简介 来自于<编程珠玑>.所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空 ...

  6. 海量数据处理之BitMap

    有这样一种场景:一台普通PC,2G内存,要求处理一个包含40亿个不重复并且没有排过序的无符号的int整数,给出一个整数,问如果快速地判断这个整数是否在文件40亿个数据当中? 问题思考: 40亿个int ...

  7. 位图法bitmap

    1.概念 1)所谓bitmap,就是用每一位(bit)来标记某个元素对应的value, 而key即是该元素,通常bitmap是一个int数组,用每一个int数的每一个bit来映射某个数据 2)由于采用 ...

  8. BitMap位图与海量数据的理解与应用

    1. Bit Map算法简介 来自于<编程珠玑>.所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空 ...

  9. Bitmap用来做大数据处理

    MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算.概念"Map(映射)"和"Reduce(归约)" Bit-map空间压缩和快速排序去 ...

随机推荐

  1. 第一篇随笔!!!THE FIRST BLOOD!!!

    注册成功,哈哈 以后就要在这扎窝了,要坚持记录下去,关于生活,关于学习. 选了个皮肤 darkgreen,不错,简洁舒服,喜欢. 好,差不多了,感觉没什么可说的了...==

  2. nlssort函数的用法以及参数

    NLSSORT,可以用来进行语言排序,且不影响当前会话. 用法示例: 拼音SELECT * FROM TEAM ORDER BY NLSSORT(排序字段,'NLS_SORT = SCHINESE_P ...

  3. [设计模式] javascript 之 迭代子模式

    迭代子模式:定义 迭代子模式,又称游标模式,是一种用于对聚集进行顺序访问规则的模式,是一种行为模式:它用于提供对聚集对象的一种统一的访问接口,使客户能够在不了解聚集对象内部结构的情况对聚集对象进行访问 ...

  4. [译]git commit

    git commit git commit命令提交stage区的快照到项目历史中去(HEAD). 被提交的快照被认为是一个项目的安全版本. Git不会修改他们, 除非你显示的要求了. 和git add ...

  5. [译]在Mac上运行ASP.NET 5

    原文:http://stephenwalther.com/archive/2015/02/03/asp-net-5-and-angularjs-part-7-running-on-a-mac 这篇文章 ...

  6. EF-Linq将查询结果转换为List<string>

    List<int> id_list = new List<int>() { 1 };//测试数据...List<string> guid_list = (from ...

  7. SQL Server数据库邮件配置

    一.数据库邮件介绍 数据库邮件是从SQL Server数据库引擎中发送电子邮件的企业解决方案,通过使用数据库邮件,数据库应用程序可以向用户发送电子邮件.邮件中可以包含查询结果,还可以包含来自网络中任何 ...

  8. Linux下运行C语言程序

    一.编写C语言的源代码 二.用gcc -c C文件名生成.o文件 三.用gcc -o 可执行文件名 .o文件名 生成可执行文件 四.输入可执行文件名前加./执行可执行文件

  9. dede自定义表单增加添加时间怎么弄

    我们在用dedecms添加自定义表单时有时想要设置一个用户提交的时间,方便查询,比如我们的客服人员查询昨天晚上下班后有哪些订单是刚生成的,比较好查看,如下图所示.那么,dedecms自定义表单增加添加 ...

  10. Back to Edit Distance(LCS + LIS)

    Given 2 permutations of integers from 1 to N, you need to find the minimum number of operations nece ...