给定一个输入文件,包含40亿个非负整数。产生一个不在该文件中的整数。内存限制:1GB
2016-11-23 00:00
411 查看
/**
* 功能:给定一个输入文件,包含40亿个非负整数。产生一个不在该文件中的整数。内存限制:1GB
* 进阶:内存限制10MB。
*/
[java] view plain copy
/**
* 思路:
*
* 1)创建包含40个亿个比特的位向量。
* 位向量(BV,bit vector)其实就是数组,利用整数(或另一种数据类型)数组紧凑地储存布尔值。每个整数可存储一串32比特或布尔值。
* 2)将BV的所有元素初始化为0.
* 3)扫描文件中的所有数字(num),并调用BV.set(num,1)。
* 4)接着,再次从索引0开始扫描BV。
* 5)返回第一个值为0的索引。
*
*
* 值的确定:
* 1)2^32——>40亿个不同的整数,一个整数4个字节。
* 2)2^30字节——>1GB——>2^33bit——>80亿比特位。每一位映射一个不同的整数,可以存储之多80亿个不同的整数。
*/
long numberOfInts=((long)Integer.MAX_VALUE)+1;
byte[] bitfield=new byte[(int) (numberOfInts/8)];
public void findOpenNumber() throws FileNotFoundException{
Scanner in=new Scanner(new FileReader("f:\\file.txt"));
while(in.hasNext()){
int n=in.nextInt();
/*
* 使用OR操作符设置一个字节的第n位,找出bitfield中相对应的数字。
* (例如,10(十进制)将对应于字节数组中索引2的第2位)
*/
bitfield[n/8]=(byte) (1<<(n%8));
}
for(int i=0;i<bitfield.length;i++){
for(int j=0;j<8;j++){
/*
* 取回每个字节的各个比特。当发现某个比特为0时,即找到相对应的值。
*/
if((bitfield[i]&(1<<j))==0){
System.out.println(i*8+j);
return;
}
}
}
}
进阶:10MB
[java] view plain copy
/**
* 思路:对数据集进行两次扫描,就可以找出不在文件中的整数。可以将全部整数划分为同等大小的区块。
* 第一次扫描数组:确定每个数组的元素个数。
* 第二次扫描位向量:确定该范围内少的数字。
*
* bitSize::第一次扫描时每个块范围的大小。
* blockNum:第一次扫描时块的个数。
*
* 值的确定:
* 1)10MB——>2^23Byte。一个整数4个字节,因此,最多包含2^21个元素的数组。
* 2)bitSize=(2^32/blockNum)<=2^21,所以,blockNum>=2^11。
* 2^11<=bitSize<=2^26。
* 在这些条件下,挑选出越靠中间的值,那么,在任何时候所诉的内存就越少。
*/
int bitSize=1048576;
int blockNum=4096;
byte[] bitfield2=new byte[bitSize/8];
int[] blocks=new int[blockNum];
public void findOpenNumber2() throws FileNotFoundException{
Scanner in=new Scanner(new FileReader("f:\\file.txt"));
int starting=-1;
while(in.hasNext()){
int n=in.nextInt();
blocks[n/bitfield2.length*8]++;
}
for(int i=0;i<blocks.length;i++){
/*
* 若小于,则说明该块中至少少了一个数字
*/
if(blocks[i]<bitfield2.length*8){
starting=i*bitfield2.length*8;
break;
}
}
in =new Scanner(new FileReader("f:\\file.txt"));
while(in.hasNext()){
int n=in.nextInt();
if(n>=starting&&n<starting+bitfield2.length*8){
bitfield2[(n-starting)/8]=(byte) (1<<((n-starting)%8));
}
}
for(int i=0;i<bitfield2.length;i++){
for(int j=0;j<8;j++){
/*
* 取回每个字节的各个比特。当发现某个比特为0时,即找到相对应的值。
*/
if((bitfield2[i]&(1<<j))==0){
System.out.println(i*8+j+starting);
return;
}
}
}
}
* 功能:给定一个输入文件,包含40亿个非负整数。产生一个不在该文件中的整数。内存限制:1GB
* 进阶:内存限制10MB。
*/
[java] view plain copy
/**
* 思路:
*
* 1)创建包含40个亿个比特的位向量。
* 位向量(BV,bit vector)其实就是数组,利用整数(或另一种数据类型)数组紧凑地储存布尔值。每个整数可存储一串32比特或布尔值。
* 2)将BV的所有元素初始化为0.
* 3)扫描文件中的所有数字(num),并调用BV.set(num,1)。
* 4)接着,再次从索引0开始扫描BV。
* 5)返回第一个值为0的索引。
*
*
* 值的确定:
* 1)2^32——>40亿个不同的整数,一个整数4个字节。
* 2)2^30字节——>1GB——>2^33bit——>80亿比特位。每一位映射一个不同的整数,可以存储之多80亿个不同的整数。
*/
long numberOfInts=((long)Integer.MAX_VALUE)+1;
byte[] bitfield=new byte[(int) (numberOfInts/8)];
public void findOpenNumber() throws FileNotFoundException{
Scanner in=new Scanner(new FileReader("f:\\file.txt"));
while(in.hasNext()){
int n=in.nextInt();
/*
* 使用OR操作符设置一个字节的第n位,找出bitfield中相对应的数字。
* (例如,10(十进制)将对应于字节数组中索引2的第2位)
*/
bitfield[n/8]=(byte) (1<<(n%8));
}
for(int i=0;i<bitfield.length;i++){
for(int j=0;j<8;j++){
/*
* 取回每个字节的各个比特。当发现某个比特为0时,即找到相对应的值。
*/
if((bitfield[i]&(1<<j))==0){
System.out.println(i*8+j);
return;
}
}
}
}
进阶:10MB
[java] view plain copy
/**
* 思路:对数据集进行两次扫描,就可以找出不在文件中的整数。可以将全部整数划分为同等大小的区块。
* 第一次扫描数组:确定每个数组的元素个数。
* 第二次扫描位向量:确定该范围内少的数字。
*
* bitSize::第一次扫描时每个块范围的大小。
* blockNum:第一次扫描时块的个数。
*
* 值的确定:
* 1)10MB——>2^23Byte。一个整数4个字节,因此,最多包含2^21个元素的数组。
* 2)bitSize=(2^32/blockNum)<=2^21,所以,blockNum>=2^11。
* 2^11<=bitSize<=2^26。
* 在这些条件下,挑选出越靠中间的值,那么,在任何时候所诉的内存就越少。
*/
int bitSize=1048576;
int blockNum=4096;
byte[] bitfield2=new byte[bitSize/8];
int[] blocks=new int[blockNum];
public void findOpenNumber2() throws FileNotFoundException{
Scanner in=new Scanner(new FileReader("f:\\file.txt"));
int starting=-1;
while(in.hasNext()){
int n=in.nextInt();
blocks[n/bitfield2.length*8]++;
}
for(int i=0;i<blocks.length;i++){
/*
* 若小于,则说明该块中至少少了一个数字
*/
if(blocks[i]<bitfield2.length*8){
starting=i*bitfield2.length*8;
break;
}
}
in =new Scanner(new FileReader("f:\\file.txt"));
while(in.hasNext()){
int n=in.nextInt();
if(n>=starting&&n<starting+bitfield2.length*8){
bitfield2[(n-starting)/8]=(byte) (1<<((n-starting)%8));
}
}
for(int i=0;i<bitfield2.length;i++){
for(int j=0;j<8;j++){
/*
* 取回每个字节的各个比特。当发现某个比特为0时,即找到相对应的值。
*/
if((bitfield2[i]&(1<<j))==0){
System.out.println(i*8+j+starting);
return;
}
}
}
}
相关文章推荐
- 扩展性与存储限制(二)——给定一个输入文件,包含40亿个非负整数。产生一个不在该文件中的整数。内存限制:1GB
- 9.10扩展性与存储限制(二)——给定一个输入文件,包含40亿个非负整数。产生一个不在该文件中的整数。内存限制:1GB
- 一个文件含有40亿个非负整数,使用1GB内存,找到一个不在该文件中的整数
- 给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数
- 一个文件中有40亿个整数,每个整数为四个字节,内存为1GB,写出一个算法:求出这个文件里的整数里不包含的一个整数。
- 给定一个最多包含40亿个随机排列的32位整数的顺序文件,找出一个不在文件中的32位整数。
- 一个文件含有40亿个非负整数,使用10MB内存,找到一个不在该文件中的整数
- 一个文件中有40亿个整数,每个整数为四个字节,内存为1GB,写出一个算法:求出这个文件里的整数里不包含的一个整数
- 一个文件中有40亿个整数,每个整数为四个字节,内存为1GB,写出一个算法:求出这个文件里的整数里不包含的一个整数
- 程序员面试金典: 9.10 扩展性与存储限制 10.3产生1个不在含40亿个整数文件中的整数
- 程序员面试金典: 9.10 扩展性与存储限制 10.3产生1个不在含40亿个整数文件中的整数---优化解法
- 在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。
- 给定一个正整数n,找到小于或等于n的非负整数,其二进制表示不包含连续的整数。
- 在一个文件中有 10G 个整数,乱序排列,要求找出中位数(内存限制为2G)
- 在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。
- 新解:给定包含4 300 000 000个32位整数的顺序文件,如何找出一个至少出现两次的整数。
- 编程珠玑 第二章 习题 2 给定一个包含4300000000个32位证书的顺序文件,求出一个至少包含两次的整数
- 一个文件中有40亿个整数,求出这个文件里的整数里不包含的一个整数
- 在一个文件中有 10G 个整数,乱序排列,要求找出中位数。内存限制为 2G。
- 给定包含4300000000个32位整数的顺序文件,如何找出一个出现至少两次的整数