位图排序

输入:一个最多包含一百万(10^6)个正整数的文件,每个数都小于n,其中n=一千万(10^7)。输入文件中没有重复的整数。

输出: 按升序排列这些数,并写入磁盘。

约束:有 1MB多(不超过2MB) 的内存空间可用,有充足的硬盘空间

一、原理

         这道题是在编程珠玑上看到的,是习题3,自己写了一下玩玩,感觉这个算法很棒,通俗易懂。

 这个问题的最好算法应当是位图:由于整数没有重复,那么可以用比特位来表示整数的存在。

比如集合  {1,2,5,4,6},

可以用位图表示为   01101110,

由于位图的第1,2,4,5,6为都是1,表示集合里存在着这几个数。

因为这个算法实现的时候,数最大为10 000 000,那么需要用10 000 000个bit的数组来表示,内存大小为 10 000 000/8/1024/1024约等于1.2M

实现需要解决以下问题有:

1) 找到数据i所对应的字节位置

2)找到数据i对应的字节中位位置

3) 判断某位是否为1, 置某位为1 

解决它:

1) 找到 对应字节位置: 32系统,相当于 i/32, 使用位操作 数据i >> 5

2)  找到对应字节的位位置: 32系统相当于 i%32, 使用位操作 数据 i&0x1F(31)

   附:(m mod n 运算,当n = 2的X次幂的时候,m mod n = m&(n-1)  ,这里32为2^5,所以是i&0X1F)

 n=2^x 写成二进制就是1后面x个0,m%n就是m的低x位。 
n-1=2^x-1 写成二进制是x个1,m&(n-1)也是取m的低x位。

3)数字 a 的 第i位 是1: 方法 a & (1 << i) ,将数据a的第 i位 置1: a | (1 << i)

二、代码

(因为C++STL中有bitset这一容器,所以实现起来并不难,我先用bitset实现,后用C++不用bitset实现)

  

 

做人要厚道,转帖请注明出处!
posted @   Zeroinger  阅读(514)  评论(0编辑  收藏  举报
无觅关联推荐,快速提升流量
点击右上角即可分享
微信分享提示