zoukankan      html  css  js  c++  java
  • 面试收集小技巧之位图实现

    之前有很多题目说到要用位图来解决问题,比如,

    1.找1到10W之间没有出现的两个数,其中这些数是乱序排放(可能数字比10W还大,比如说40亿)

    2.一个最多包含n个正整数的文件,每个数都小于n,其中n=107。如果在输入文件中有任何正数重复出现就是致命错误。没有其他数据与该正数相关联。输出按升序排列的输入正数的列表

    3.给出40亿个数,搜索某一个数是否存在于这些数之中

    4.两个整数集合A和B,求交集。

    这里面就有位图的用武之地了,位图的好处是一来位操作比较快,二来占用空间会比较小, 比如说10W个整数,如果全部加载到内存的话大概需要105*4B(大约400KB),但是如果知道这些数最大为105的话,只需要105bit(大约10KB),时间效率和空间效率都有了很大提高。

    以问题2为例,位图法解题思路如下:
    a.分配位图空间,初始每位置零:最多n(n=107)个数,怎么在语言中具体实现这个位图。

    b.遍历文件,出现过的整数对应的bit位置为1。

    c.顺序遍历位图,为1的bit位的索引按序输出。

    这个思路在具体实现时,分配空间怎么分?置位操作怎么实现?

    对于c语言,可以用整数或者字符数组来模拟这么一个大的位图,以整数为例,申请一个数组int bitmap[1000]即能表示32000个bit位,因为数组是连续存放的,所以可以用来模拟。因此对于最大值和最小值相差为N(N可能非常大)的状况,需要整数数组的大小是N/32.进行置位操作是,首先通过索引定位到位所在整数的位置(若索引为i,那么整数在整数数组中的位置为i/32即i>>5),然后确定这一位在索引到的整数中的哪一位(i%32,即i&0x1F)。具体操作代码如下:

    #define MaxCount 100000
    
    int bitmap[1+MaxCount/32];
    
    void set(int index)
    
    {
    
    	assert(index<MaxCount);
    
    	assert(index>=0);
    
    	bitmap[index>>5]|=(1<<(index&0x1F);
    
    }
    
    void reset(int index)
    
    {
    
    	assert(index<MaxCount);
    
    	assert(index>=0);
    
    	bitmap[index>>5]&=(~(1<<(index&0x1F)));
    
    }
    

    而对于C++,还可以用bitset这一数据结构直接来实现。

    #include <iostream>
    #include<bitset> 
    using namespace std;
    int main(int argc, char *argv[])
    {
        const int max = 10000000;
        
        int n,i;
        bitset<max+1> bit;                     //初始默认所有二进制位为0 
        
        while(scanf("%d",&n)!=EOF)
        {
            bit.set(n,1);                   //将第n位置1               
        }    
        for(i=0;i<=max+1;i++)
        {
            if(bit[i]==1)
                printf("%d ",i);
        }
        return 0;
    }
  • 相关阅读:
    函数式编程(三元运算、文件操作、函数、装饰器)
    开发基础(练习题)
    开发基础(字符串操作、元祖、元组、Hash、字典、集合、字符编码转换)
    开发基础(字符编码、列表操作)
    开发基础 (变量、数据类型、格式化输出、运算符、流程控制、while循环)
    [LeetCode] 127. 单词接龙
    [LeetCode] 126. 单词接龙 II
    [LeetCode] 122. 买卖股票的最佳时机 II
    [LeetCode] 124. 二叉树中的最大路径和
    [LeetCode] 125. 验证回文串
  • 原文地址:https://www.cnblogs.com/obama/p/3028561.html
Copyright © 2011-2022 走看看