发现4十亿(再次)失踪人数(Find missing number from 4 billion (

2019-10-16 15:09发布

似乎已经问过很多次的问题是关于检测在4个十亿数字的遗漏号码。
所述recomended方法似乎是使用一个bitset(当存储器限制是问题的一部分)。
一个例子后是这样的: 发现-一个整数-不中,四十亿赋予的,那些和我也可以在这里SO链接到更多。

我的问题是:位集方法似乎隐含asume这些数字是不可否定。 正如我挂到后一个例子,有在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(); 可以返回一个负数。

所以我想在某种程度上我的困惑是约2份对这类问题/运动:
1)可一个bitset来表示负数? 怎么样?
2)是解决主题相关的特定编程语言的问题? 例如,在C ++那里有无符号数我想一个可以接受的假设范围非负。

可能有人请帮助我理解这一点?

Answer 1:

尝试

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[]



Answer 2:

那么有明显的解决方案:因为我们知道,每一个号码都有特定的范围[A,B)你可以添加到所有数字的下边界得到保证的正数。

现在,这并不对任意长的数字打工,但那时这通常不是问题



文章来源: Find missing number from 4 billion (again)