问题描述

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

输出:按升序排列的输入正数的列表。

约束:最多有1MB的内存空间可用,有充足的磁盘存储空间可用。运行时间最多几分钟,运行时间为10秒就不需要进一步优化。

程序设计与实现概要:

应用位图或位向量表示集合。可用一个10位长的字符串来表示一个所有元素都小于10的简单的非负整数集合,例如,可以用如下字符串表示集合{1,2,4,5,8}:

0  1  1  1  0  1  0  0  1  0  0

代表集合中数值的位都置为1,其他左所有的位置为0.编程珠玑当中建议是一年个一个具有1000万个位的字符串来表示这个文件,那么这个文件的所占容量为10000000 bit=107bit,不到1MB的大小,其中,当且精当整数i在文件中存在,第i为1,这个表示利用了该问题的三个在排序问题中不常见的属性:输入数据限制在相对较小的范围内;数据没有重复;而且对于每条记录而言,除了单一个整数外没有其他关联数据。

如给定表示文件中整数集合的位图数据结构,则可以分三个阶段来编写程序

第一阶段:将所有的位都置为0,从而将集合初始化为空。

第二阶段:通过读入文件中的每个整数来建立集合,将每个对应的位置都置为1。

第三阶段:检验每一位,如果该为为1,就输出对应的整数,有此产生有序的输出文件。

下面的C语言的实现和C++的实现代码

C语言:

所申请的int数组如下所示:

字节位置=数据/32;(采用位运算即右移5位)

位位置=数据%32;(采用位运算即跟0X1F进行与操作)。

#include <stdio.h>
#define MAX 10000000
#define SHIFT 5
#define MASK 0x1F
#define DIGITS 32int a[1+MAX/DIGITS];void set(int n)                                //将逻辑位置为n的二进制位置为1
{a[n>>SHIFT] |=(1<<(n&MASK));               //n>>SHIFT右移5位相当于除以32求算字节位置,n&MASK相当于对32取余即求位位置,
}                                                void clear(int n)
{a[n>>SHIFT] &=(~(1<<(n&MASK)));           //将逻辑位置为n的二进制位置为0
}int test(int n)
{return a[n>>SHIFT] & (1<<(n&MASK));        //测试逻辑位置为n的二进制位是否为1
}int main(int argc, char *argv[])
{int i,n;for(i=1;i<=MAX;i++){clear(i);}    while(scanf("%d",&n)!=EOF){set(n);}for(i=1;i<=MAX;i++){if(test(i))printf("%d ",i);}return 0;
}

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;
}

---------------------------------------------------

扩展:
给40亿个不重复的unsigned int的整数,没有排过序,然后再给一个数,如果快速判断这个数是否在那40亿个数当中。(腾讯面试题)
用位图法:40亿unsigned int,则用位图表示的话需要大小为40亿个bit=4*109 bit=0.5*109 bytes 因此申请的内存只需要大小约为512MB左右,这样在内存每个bit代表一个unsigned int整数,并将每个bit初始化为0,然后将40亿个unsigned int的整数读入,每个unsigned int的整数对应bit设置为1,读入后,最后看所给定的数对应的bit是否为1,是1存在,否则不存在。

编程珠玑:位图法排序相关推荐

  1. 编程珠玑--位图法排序

    位图法是<编程珠玑>第一章中出现的磁盘排序算法. 题目:一个最多包含n个正整数的文件,每个数都小于n,其中n=10^7,且所有正整数都不重复.求如何将这n个正整数升序排列. 约束:最多有1 ...

  2. Java 位图法排序

    java JDK里面容器类的排序算法使用的主要是插入排序和归并排序,可能不同版本的实现有所不同,关键代码如下: /*** Performs a sort on the section of the a ...

  3. java位图_Java 位图法排序的使用方法

    java JDK里面容器类的排序算法使用的主要是插入排序和归并排序,可能不同版本的实现有所不同,关键代码如下: /** * Performs a sort on the section of the ...

  4. java 位图法_位图法对大量整数进行排序

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

  5. 编程珠玑读书笔记之磁盘文件排序

    输入: 所输入的是一个文件,至多包含n个正整数,每个正整数都要小于n,这是 n = 10^7.如果输入时某个整数出现了两次,就会产生一个致命的错误.这些整数与其他任何数据都不关联. 输出: 以增序形式 ...

  6. 磁盘文件排序-编程珠玑

    http://www.cnblogs.com/luxiaoxun/archive/2012/09/12/2681268.html http://blog.csdn.net/wangkechuang/a ...

  7. PTA 基础编程题目集 7-27 冒泡法排序 C语言

    PTA 基础编程题目集 7-27 冒泡法排序 C语言 将N个整数按从小到大排序的冒泡排序法是这样工作的:从头到尾比较相邻两个元素,如果前面的元素大于其紧随的后面元素,则交换它们.通过一遍扫描,则最后一 ...

  8. linux编程排序,Linux下简单的c编程——选择法排序

    针对函数和数组的C语言的学习,我今天来写一个比较典型的数组和函数的结合的例子--选择法排序 选择法顾名思义,先选择最大和最小的数,然后再进行排序 第一步首先附上我的代码.第一段代码是实现从大到小排序, ...

  9. 编程珠玑第二章习题答案

    转载自互联网,并做了修改 1.提供单词和词典,找到该单词的所有变位词,可以事先花时间和空间处理下该词典. 为了找出给定单词的所有变位词,首先是计算给定单词的标识.如果不允许预处理,只能够顺序读取文件, ...

  10. 《编程珠玑(第2版•修订版)》—第2章2.2节无处不在的二分搜索

    本节书摘来自异步社区<编程珠玑(第2版•修订版)>一书中的第2章2.2节无处不在的二分搜索,作者[美]Jon Bentley,更多章节内容可以访问云栖社区"异步社区"公 ...

最新文章

  1. java将读到的换行符存储到数据表中_Java学习之路013天
  2. 虚拟串口最大传输速率_【干货】详解RS232、RS485、RS422、串口amp;amp;握手
  3. hdu 1046 完数
  4. 分布式系统一致性问题解决实战
  5. (转)flash位图缓存cacheAsBitmap
  6. windbg断点学习总结
  7. JavaScript单元测试ABC
  8. 入门Python,这些优点你要知道
  9. xmind快捷键_XMind思维导图软件最全面的使用教程!
  10. unity 里调试native code
  11. 零件缝隙平行线距离检测4
  12. 稳压管(齐纳二极管)封装型号大全
  13. 【java】java 安全 jaas 文件 何时 解析 以及 怎么解析的
  14. workstation服务启动报错。错误1075:依存服务不存在, 或已标记为删除的解决方法
  15. Unity获取IOS端相机权限的状态
  16. 什么是长连接 | 短连接?
  17. 汕头好的计算机学校有哪些,2021年汕头所有小学名单及排名,汕头最好的小学有哪些...
  18. 青龙面板----今日头条脚本修复版
  19. python递归法画樱花_Python——画一棵漂亮的樱花树
  20. mysql 设置为空_MySQL中可为空的字段设置为NULL还是NOT NULL

热门文章

  1. python所有组合,在python中组合n个列表的所有元素
  2. php中函数怎么调用参,php – 将参数传递给可调用函数
  3. centos7 防火墙_【Linux简单实用小命令001】CentOS 7、8的防火墙端口开放
  4. javascript 内存和连等赋值
  5. IBM主机增加“交易实时分析”新能力
  6. #浪潮之巅#苹果公司和乔布斯神话----有感
  7. 应用程序中的服务器错误
  8. 网外(Internet)访问代理服务器内部的实现方法
  9. 蓝桥杯 大整数乘法 试题 算法训练 P0805
  10. python采集人脸_python获取人脸的代码分享