zoukankan      html  css  js  c++  java
  • 位图排序

    输入:一个最多包含一百万(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实现)

    /**************************************
    *                                     *
    *  -*- coding: utf-8 -*-              *
    *  @Date    : 2016-05-12 18:54:47     *
    *  @Author  : Zeroinger               *
    *                                     *
     *************************************/
    #include <iostream>
    #include <algorithm>
    #include <time.h>
    #include <bitset>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <list>
    #include <map>
    #include <set>
    #include <sstream>
    #include <string>
    #include <bitset>
    #include <vector>
    #include <cstdio>
    #include <algorithm>
    #include <fstream>
    using namespace std;
    #define MAXN 10000000
    #define NUM  1000000
    #define SHIFT 5
    #define MARK 0x1F
    #define DIGITS 32
    int a[MAXN+1];
    //bitset <MAXN+1> bit;
    int b[1+MAXN/32];
    void st(int i)
    {
        b[i >> SHIFT] |= (1 << (i & MARK));
    }
    
    int test(int i)
    {
        return b[i >> SHIFT] & (1 << (i & MARK));
    }
    
    void clr(int i)
    {
        b[i >> SHIFT] &= ~(1 << (i & MARK));
    }
    void write()
    {
    
        for(int i=0; i<=MAXN; i++)
        {
            a[i]=i+1;
        }
    }
    int getrand(int a,int b)
    {
        return  ((a+RAND_MAX * rand() + rand()) % (b-a+1));
    }
    void getdata()
    {
        for(int i=0; i<NUM; i++)
        {
                int t=getrand(i,MAXN);
                swap(a[i],a[t]);
        }
        FILE *fp;
        fp = fopen("test_before.txt", "w");
        if(fp == NULL)
        {
            cout << "随机数文件生成失败,error in make_data()." << endl;
        }
        int cc=0;
        for(int i = 0; i < NUM; i++)
        {
            fprintf(fp, "%7d  ", a[i]);
            cc++;
            if(cc%20==0)
            fprintf(fp, "
    ");
    
        }
        cout<<cc<<endl;
        fclose(fp);
        cout << "随机数文件生成成功." << endl;
    }
    int main()
    {
       // bit.reset();
       for(int i=0;i<MAXN;i++)
       {
           clr(i);
       }
        write();
        getdata();
        FILE *fpsrc;
        fpsrc = fopen("test_before.txt", "r");
        if(fpsrc == NULL)
        {
            cout << "打开文件失败" << endl;
            return 0;
        }
    
        int data;
        while(fscanf(fpsrc, "%d", &data) != EOF)
        {
    
               // bit.set(data,1);
               st(data);
    
        }
        FILE *fpdst;
        fpdst = fopen("test_after.txt", "w");
        if(fpdst == NULL)
        {
            cout << "打开文件失败" << endl;
            return 0;
        }
        int c=0;
        for(int i = 0; i <MAXN+1; i++)
        {
            if(test(i)/*bit[i] == 1*/)
            {
                fprintf(fpdst, "%7d ", i);
                c++;
                if(c%20==0)
                  fprintf(fpdst, "
    ");
    
            }
        }
        cout<<c<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    不可或缺 Windows Native (15)
    不可或缺 Windows Native (14)
    不可或缺 Windows Native (13)
    不可或缺 Windows Native (12)
    不可或缺 Windows Native (11)
    不可或缺 Windows Native (10)
    不可或缺 Windows Native (9)
    不可或缺 Windows Native (8)
    不可或缺 Windows Native (7)
    不可或缺 Windows Native (6)
  • 原文地址:https://www.cnblogs.com/Zeroinger/p/5495410.html
Copyright © 2011-2022 走看看