careercup-扩展性和存储限制10.3
题目
给你一个文件,里面包含40亿个整数,写一个算法找出该文件中不包含的一个整数, 假设你有1GB内存可用。
如果你只有10MB的内存呢?
解答
我们先来做个算术题,40亿个整数大概有多大?
* ^ * 4B = 16GB (大约值,因为不是按照2的幂来做单位换算)
这个明显无法一次性装入内存中。但是,如果我们用计算机中的一位来表示某个数出现与否, 就可以减少内存使用量。比如在一块连续的内存区域,15出现,则将第15位置1。 这个就是Bit Map算法。关于这个算法,网上有篇文章写得挺通俗易懂的,推荐:
http://blog.csdn.net/hguisu/article/details/7880288
如果用Bit Map算法,一个整数用一位表示出现与否,需要的内存大小是:
* ^ b = * ^ B = .5GB
而我们有1GB的内存,因此该算法可行。由于Bit Map只能处理非负数, (没有说在第-1位上置1的),因此对于有符号整数,可以将所有的数加上0x7FFFFFFF, 将数据移动到正半轴,找到一个满足条件的数再减去0x7FFFFFFF即可。 因此本文只考虑无符号整数,对于有负数的情况,按照上面的方法处理即可。
我们遍历一遍文件,将出现的数对应的那一位置1,然后遍历这些位, 找到第一个有0的位即可,这一位对应的数没有出现。代码如下:
#include <iostream>
#include <cstdio>
using namespace std; int main(){
// freopen("12.3.in", "w", stdout);
// int miss = 12345;
// for(int i=0; i<20000; ++i){
// if(i == miss) continue;
// cout<<i<<endl;
// }
// fclose(stdout); freopen("12.3.in", "r", stdin); int int_len = sizeof(int) * ;
int bit_len = 0xFFFFFFFF / int_len;
int* bit = new int[bit_len];
int v;
while(scanf("%d", &v) != EOF){
bit[v/int_len] |= <<(v%int_len);
}
bool found = false;
for(int i=; i<bit_len; ++i){
for(int j=; j<int_len; ++j){
if((bit[i] & (<<j)) == ){
cout<<i*int_len + j<<endl;
found = true;
break;
} }
if(found) break;
} delete[] bit;
fclose(stdin);
return ;
}
而我们有1GB的内存,因此该算法可行。由于Bit Map只能处理非负数, (没有说在第-1位上置1的),因此对于有符号整数,可以将所有的数加上0x7FFFFFFF, 将数据移动到正半轴,找到一个满足条件的数再减去0x7FFFFFFF即可。 因此本文只考虑无符号整数,对于有负数的情况,按照上面的方法处理即可。
接下来我们就可以用Bit Map算法了。我们再遍历一遍数据, 把落在这个块的数对应的位置1(我们要先把这个数归约到0到blocksize之间)。 最后我们找到这个块中第一个为0的位,其对应的数就是一个没有出现在该文件中的数。 代码如下:
#include <iostream>
#include <cstdio>
using namespace std; int main(){
freopen("12.3.in", "r", stdin);// 20000 number
int int_len = sizeof(int) * ;
int totalnum = ;
int blocksize = ;
int blocknum = totalnum / blocksize;
int* block = new int[blocknum];
int* bit = new int[blocksize/int_len+];
int v;
while(scanf("%d", &v) != EOF){
++block[v/blocksize];
}
fclose(stdin);
int start;
for(int i=; i<blocknum; ++i){
if(block[i] < blocksize){
start = i * blocksize;
break;
}
}
freopen("12.3.in", "r", stdin);
while(scanf("%d", &v) != EOF){
if(v>=start && v<start+blocksize){
v -= start; // make v in [0, blocksize)
bit[v/int_len] |= <<(v%int_len);
}
} bool found = false;
for(int i=; i<blocksize/int_len+; ++i){
for(int j=; j<int_len; ++j){
if((bit[i] & (<<j)) == ){
cout<<i*int_len+j+start<<endl;
found = true;
break;
}
}
if(found) break;
} delete[] block;
delete[] bit;
fclose(stdin);
return ;
}
careercup-扩展性和存储限制10.3的更多相关文章
- careercup-扩展性和存储限制10.6
题目 你有10亿个url,每个url对应一个非常大的网页.你怎么检测重复的网页? 解答 网页大,数量多,要把它们载入内存是不现实的. 因此我们需要一个更简短的方式来表示这些网页.而hash表正是干这事 ...
- careercup-扩展性和存储限制10.4
题目 有一个数组,里面的数在1到N之间,N最大为32000.数组中可能有重复的元素(即有的元素 存在2份),你并不知道N是多少.给你4KB的内存,你怎么把数组中重复的元素打印出来. 解答 我们有4KB ...
- OpenStack 企业私有云的若干需求(6):大规模扩展性支持
本系列会介绍OpenStack 企业私有云的几个需求: 自动扩展(Auto-scaling)支持 多租户和租户隔离 (multi-tenancy and tenancy isolation) 混合云( ...
- 使用Lua脚本语言开发出高扩展性的系统,AgileEAS.NET SOA中间件Lua脚本引擎介绍
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- MySQL - 扩展性 3 负载均衡:眼花缭乱迷人眼
负载均衡的基本思路很简单: 在一个服务器集群中尽可能地的平均负载量. 基于这个思路,我们通常的做法是在服务器前端设置一个负载均衡器.负载均衡器的作用是将请求的连接路由到最空闲的可用服务器上.如图 1, ...
- Atitit.软件架构高扩展性and兼容性原理与概论实践attilax总结
Atitit.软件架构高扩展性and兼容性原理与概论实践attilax总结 1. 什么是可扩展的应用程序?1 2. 松耦合(ioc)2 3. 接口的思考 2 4. 单一用途&模块化,小粒度化2 ...
- jetbrick,新一代 Java 模板引擎,具有高性能和高扩展性
新一代 Java 模板引擎,具有高性能和高扩展性. <!-- Jetbrick Template Engineer --> <dependency> <groupId&g ...
- Android ImageCache图片缓存,使用简单,支持预取,支持多种缓存算法,支持不同网络类型,扩展性强
本文主要介绍一个支持图片自动预取.支持多种缓存算法的图片缓存的使用及功能.图片较大需要SD卡保存情况推荐使用ImageSDCardCache. 与Android LruCache相比主要特性:(1). ...
- Java并发编程:性能、扩展性和响应
1.介绍 本文讨论的重点在于多线程应用程序的性能问题.我们会先给性能和扩展性下一个定义,然后再仔细学习一下Amdahl法则.下面的内容我们会考察一下如何用不同的技术方法来减少锁竞争,以及如何用代码来实 ...
随机推荐
- Android源码下编译APK步骤
1.进入android源码目录下的build下执行:source envsetup.sh 后继续在该路径下执行lunch. 2.编写完成工程 3.编写Android.mk文件,放入工程目录下 ...
- cookie初探——封装和使用cookie(内含彩蛋)
一.什么是cookie? 页面用来保存信息,如:自动登录.记住用户名 二.cookie的特性1.同一个网站中所有页面共享一套cookie2.数量.大小有限3.有过期时间 三.js中使用cookie d ...
- web前端开发需要具备的技能
web前端开发需要具备以下7种技能: 1.页面标记(HTML) HTML页面固定,标签不多,相对来说学起来比较容易.编写HTML代码需遵循HTML代码规范(http://www.cnblogs.com ...
- MongoDB 创建集合
createCollection() 方法 MongoDB db.createCollection(name, options) 是用来创建集合. 语法: 基本的 createCollection() ...
- Linux的inode的理解 ZZ
文件名 -> inode -> device block 转自:http://www.ruanyifeng.com/blog/2011/12/inode.htmlhttp://blog.s ...
- 代码分析工具推荐Understand
之前看ogitor ,第一次看到那么多代码~~不知道从哪里下手,而且好多东西都不会Ogre什么的都不是很清楚,对ogitor的代码结构的了解就更不用提了.晕头转向的 不知道从哪里下手,一点点的看起来好 ...
- 使用Python批量合并PDF文件(带书签功能)
网上找了几个合并pdf的软件,发现不是很好用,一般都没有添加书签的功能. 又去找了下python合并pdf的脚本,发现也没有添加书签的功能的. 于是自己动手编写了一个小工具,使用了PyPDF2. 下面 ...
- wcf 配置与代码创建
<behaviors> <serviceBehaviors> <behavior name="MyServiceBehavior"> <s ...
- mysql获取表列信息、主键信息
/** * 获取物理表中已存在的列信息 * @param tbName 表名 * @return results 查询结果 */ fun getExistColumnInfo(tbName:Strin ...
- Vim快捷输出查找寄存器的内容(去除\<,\>和\V)
Vim自带的*搜索会自动在单词两头加上\<和\>,使用第三方的vnoremap *,则是加上前缀\V, 当我们想要输出刚刚搜索的内容时可用<C-r>/,但是很可能会带上多余的符 ...