に裏打ちされたビットベクトルを作成しようとしています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