Cra*_*lus 0 java algorithm bit-manipulation bit bitvector
我正在尝试创建一个支持的位向量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;
}
}
Run Code Online (Sandbox Code Playgroud)
我知道也许我应该使用byte[]替代等但我想知道为什么这种方式不起作用.
我的想法是int从流中传入并保留低16位并将相应的位标记为set.所以当我迭代向量时,我会发现缺少数字(用低16位表示).
但我得错了结果.所以我相信我的处理是错误的.
有任何想法吗?
更新:
我有一个32位整数流.当我读到它时,我尝试使用低16位并设置位向量(代码已发布)来标记缺失的数字.
我还试图找到第二次读取流的上部16位丢失.
因此,虽然丢失的数字是: 231719592=(1101110011111100001010101000)=(3535- 49832)当我读取流时,我没有得到49832丢失的低位但是65536
UPDATE2:
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);
}
Run Code Online (Sandbox Code Playgroud)
我明白了:
Missing number=231719592
Found upper bits:3535 //CORRECT
Lower bits:-1 //WRONG
Actual missing number=-1 //WRONG
Run Code Online (Sandbox Code Playgroud)
我认为有两个问题:
您的阵列有65536个条目,但每个条目中存储32位,因此您只需要65536/32个条目.
您在每个int中存储32位,但在查找间隙时仅检查j从0到7
第一个错误意味着您的程序将65536报告为缺失的16位数字.第二个错误意味着您的程序没有发现丢失的号码.
即改变
int[] vector = new int[1 << 16];
Run Code Online (Sandbox Code Playgroud)
至
int[] vector = new int[1 << (16-5)];
Run Code Online (Sandbox Code Playgroud)
并改变
for(int j = 0; j < 8; j++)
Run Code Online (Sandbox Code Playgroud)
至
for(int j = 0; j < 32; j++)
Run Code Online (Sandbox Code Playgroud)
从评论来看,问题实际上是如何找到RAM有限的缺失数字.这个问题的答案可以在stackoverflow上找到.
更高级别的代码中还有一个错误.
在填充bitset的第二次传递期间,您应该只包含具有匹配的高位的数字.
即改变
v.setBit(sc.nextInt());
Run Code Online (Sandbox Code Playgroud)
喜欢的东西
int nx = sc.nextInt();
if (getIdx(nx)==missingUpper)
v.setBit(nx);
Run Code Online (Sandbox Code Playgroud)