【发布时间】:2012-11-25 16:58:57
【问题描述】:
我正在尝试创建一个由int[] 支持的位向量。
所以我有以下代码:
public class BitVector {
int[] vector = new int[1 << 16];
public void setBit(int nextInt) {
nextInt = nextInt & 0xFFFF;
int pos = nextInt / 32;
int offset = nextInt % 32;
vector[pos] |= (1 << offset);
}
public int findClearedBit() {
for(int i = 0; i < vector.length; i++){
for(int j = 0; j < 8; j++){
if((vector[i] & (1 << j)) == 0)
return i * 32 + j;
}
}
return -1;
}
}
我知道也许我应该改用 byte[] 等,但我想知道为什么这种方式不起作用。
这个想法是我从一个流中传入int,并保留低16位并将相应的位标记为设置。因此,当我遍历向量时,我会发现缺少数字(由低 16 位表示)。
但我得到错误的结果。所以我相信我的处理是错误的。
有什么想法吗?
更新:
我有一个 32 位整数流。当我阅读它们时,我尝试通过使用低 16 位 并设置位向量(代码已发布)来标记缺失的数字。
我还尝试找到第二次读取流时丢失的高 16 位。
因此,虽然缺少的数字是:231719592 = (1101110011111100001010101000) = (3535-49832)
当我阅读流时,我没有得到49832 作为缺少的低位,而是65536
更新2:
public int findMissingInt(File f)throws Exception{
Scanner sc = new Scanner(f);
int SIZE = 1 << 16;
int[] occurences = new int[SIZE];
while(sc.hasNext()){
occurences[getIdx(sc.nextInt())]++;
}
int missingUpper = -1;
for(int i = 0; i < occurences.length; i++){
if(occurences[i] < SIZE){
System.out.println("Found upper bits:"+i);
missingUpper = i;
break;
}
}
if(missingUpper == -1){
return -1;
}
//Arrays.fill(occurences, 0); //I reused this. Bellow changed after answer of Peter de Rivaz
BitVector v = new BitVector(new int[1 << (16-5)]);
sc = new Scanner(f);
while(sc.hasNext()){
v.setBit(sc.nextInt());
}
int missingLower = v.findClearedBit();
System.out.println("Lower bits:"+missingLower);
return createNumber(missingUpper, missingLower);
}
private int createNumber(int missingUpper, int missingLower) {
int result = missingUpper;
result = result << 16;
return result | missingLower;
}
public int getIdx(int nextInt) {
return (nextInt >>> 16);
}
我明白了:
Missing number=231719592
Found upper bits:3535 //CORRECT
Lower bits:-1 //WRONG
Actual missing number=-1 //WRONG
【问题讨论】:
-
你这样做是为了好玩吗?因为Java中内置了
BitSet。 -
@TomaszNurkiewicz:面试练习。
-
我不太清楚您要做什么,您能否提供一些预期的示例输入/输出
-
你的代码适合我。
-
@DanteisnotaGeek:请参阅更新的 OP
标签: java algorithm bit-manipulation bit bitvector