简体   繁体   中英

Implementing a very efficient bit structure

I'm looking for a solution in pesudo code or java or js for the following problem:

We need to implement an efficient bit structure to hold data for N bits (you could think of the bits as booleans as well, on/off).

We need to support the following methods: init(n) get(index) set(index, True/False) setAll(True/false)

Now I got to a solution with o(1) in all except for init that is o(n). The idea was to create an array where each index saves value for a bit. In order to support the setAll I would also save a timestamp withe the bit vapue to know if to take the value from tge array or from tge last setAll value. The o(n) in init is because we need to go through the array to nullify it, otherwise it will have garbage which can be ANYTHING. Now I was asked to find a solution where the init is also o(1) (we can create an array, but we cant clear the garbage, the garbage might even look like valid data which is wrong and make the solution bad, we need a solution that works 100%).

Update: This is an algorithmic qiestion and not a language specific one. I encountered it in an interview question. Also using an integer to represent the bit array is not good enough because of memory limits. I was tipped that it has something to do with some kind of smart handling of garbage data in the array without ckeaning it in the init, using some kind of mechanism to not fall because if the garbage data in the array (but I'm not sure how).

Make lazy data structure based on hashmap (while hashmap sometimes might have worse access time than o(1)) with 32-bit values (8,16,64 ints are suitable too) for storage and auxiliary field InitFlag

To clear all, make empty map with InitFlag = 0 (deleting old map is GC's work in Java, isn't it?)

To set all, make empty map with InitFlag = 1

When changing some bit, check whether corresponding int key bitnum/32 exists. If yes, just change bitnum&32 bit, if not and bit value differs from InitFlag - create key with value based on InitFlag (all zeros or all ones) and change needed bit.

When retrieving some bit, check whether corresponding key exists. If yes, extract bit, if not - get InitFlag value

SetAll(0):   ifl = 0, map - {}
SetBit(35):   ifl = 0, map - {1 : 0x10}
SetBit(32):   ifl = 0, map - {1 : 0x12}
ClearBit(32):   ifl = 0, map - {1 : 0x10}
ClearBit(1):   do nothing, ifl = 0, map - {1 : 0x10}
GetBit(1):     key=0 doesn't exist,  return ifl=0
GetBit(35):     key=1 exists,  return map[1]>>3 =1
SetAll(1):      ifl = 1, map = {}
SetBit(35):     do nothing
ClearBit(35):   ifl = 1, map - {1 : 0xFFFFFFF7 = 0b...11110111}
and so on

If this is a college/high-school computer science test or homework assignment question - I suspect they are trying to get you to use BOOLEAN BIT-WISE LOGIC - specifically, saving the bit inside of an int or a long. I suspect (but I'm not a mind-reader - and I could be wrong!) that using "Arrays" is exactly what your teacher would want you to avoid.

For instance - this quote is copied from Google's Search Reults:

long: The long data type is a 64-bit two's complement integer . The signed long has a minimum value of -263 and a maximum value of 263-1. In Java SE 8 and later, you can use the long data type to represent an unsigned 64-bit long, which has a minimum value of 0 and a maximum value of 264-1

What that means is that a single long variable in Java could store 64 of your bit-wise values:

long storage;
// To get the first bit-value, use logical-or ('|') and get the bit.
boolean result1 = (boolean) storage | 0b00000001; // Gets the first bit in 'storage'
boolean result2 = (boolean) storage | 0b00000010; // Gets the second
boolean result3 = (boolean) storage | 0b00000100; // Gets the third
...
boolean result8 = (boolean) storage | 0b10000000; // Gets the eighth result.

I could write the entire thing for you, but I'm not 100% sure of your actual specifications - if you use a long, you can only store 64 separate binary values. If you want an arbitrary number of values, you would have to use as many 'long' as you need.

Here is a SO posts about binary / boolean values: Binary representation in Java

Here is a SO post about bit-shifting: Java - Circular shift using bitwise operations

Again, it would be a job, and I'm not going to write the entire project. However, the get(int index) and set(int index, boolean val) methods would involve bit-wise shifting of the number 1.

int pos = 1;
pos = pos << 5;  // This would function as a 'pointer' to the fifth element of the binary number list.
storage | pos;  // This retrieves the value stored as position 5.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM