似乎已经被问过很多次的问题即将在40亿个数字中检测到丢失的数字。
推荐的方法似乎是使用bitset(当内存约束是问题的一部分时)
一个示例帖子是:find-an-integer-not-among-four-billion-given-ones我还可以在SO中链接到更多。
我的问题如下:bitset方法似乎隐含地认为数字非 -negative。作为我链接的帖子中的一个例子,Java中有这个代码片段:
int radix = 8;
byte[] bitfield = new byte[0xffffffff/radix];
void F() throws FileNotFoundException{
Scanner in = new Scanner(new FileReader("a.txt"));
while(in.hasNextInt()){
int n = in.nextInt();
bitfield[n/radix] |= (1 << (n%radix));
}
for(int i = 0; i< bitfield.lenght; i++){
for(int j =0; j<radix; j++){
if( (bitfield[i] & (1<<j)) == 0) System.out.print(i*radix+j);
}
}
}
但在Java中,所有整数都是签名的。因此,发布的代码将为负数打破。此int n = in.nextInt();
可以返回否定。
所以我想我的混乱是关于这种问题/练习的两个部分:
1)可以使用bitset来表示负数吗?怎么样?
2)问题的解决方案是否与某种特定的编程语言有关?例如。在C ++中,有无符号数,我想可以接受范围是非负数的假设。
有人可以帮我理解这个吗?
答案 0 :(得分:4)
试
long n = in.nextInt() & 0xFFFFFFFFL;
bitfield[(int) (n/radix)] |= (1 << (n%radix));
或使用
final int bits = 3;
bitfield[(int) (n >>> bits)] |= (1 << (n & ((1 << bits) -1)));
信
System.out.print((int) (i*radix+j));
您可能会发现使用和int[]
或long[]
比使用byte[]
答案 1 :(得分:3)
嗯,这是一个明显的解决方案:由于我们知道每个数字都有一个特定的范围[a,b],你可以将下边界加到所有数字上,以获得保证的正数。
现在这对任意长数都不起作用,但那通常不是问题