BitVector32 is a wrapper (or you can call it an abstraction) around C # bit operations. For example, the following two statements return the same result:
- 1 <1
- BitVector32.CreateMask (1)
Let's say there is an integer array containing some repeating numbers. We want to find all the duplicates. Of course, you can simply use the GroupBy function in Linq, but do not pretend that we do not have Linq.
The first option is a brute force approach, where each element will be compared with each element in this array:
foreach(int i in list) { foreach(int j in list) { if (i == j) {
Since the brute force approach will result in N square runtimes, which is pretty inefficient, we might consider using a HashSet that will provide constant search time or O (1)
HashSet<int> hashSet = new HashSet<int>(); foreach(int i in list) { if (hashSet.Contains(i)) {
This approach will result in linear runtime or O (n). However, this requires additional memory n * 4 bytes (assuming we are talking about a 32-bit integer value)
The third approach is similar to using hashset, except that it requires less memory using a boolean array
bool[] masks = new bool[list.Length]; for (int i = 0; i < list.length; i++) { if (masks[list[i]]) {
it uses a boolean array instead of a HashSet. It has the same runtime as O (n), but requires 1/4 of the memory size, since the bool type takes 1 byte (8 bits), while the integer takes 4 bytes (32 bits)
Finally, we can solve this problem using the BitVector32 class or our own bit offset operations.
int check = 0; for (int i=0; i < list.Length; i++) { int mask = 1 << list[i]; if (check & mask == mask) {
This will also result in a linear trigger time of only 32 bits of memory. So the memory usage is n / 32. Of course, this will not work if the maximum value in the array is greater than 32. We can use a 64-bit unsigned integer to increase the number of slots in the mask, but it still has a very short limit. In this case, if you create a BitVectory32 array, and you can transfer the bit to the BitVector32 object in the next index of the array. For example, the code would look something like this:
BitVector32[] bitVectorArray = new BitVector32[maxValue / 32]; bitVectorArray[list[i] / 32] = 1 << list[i] % 32;
Thus, you do not need to be limited to a 32-bit size limit. You can increase the size of a large mask indefinitely while memory capacity allows. So, all together:
// This code assumes you know the range of the number in the array BitVector32[] bitVectorArray = new BitVector32[maxValue / 32]; for (int i=0; i < list.Length; i++) { int mask = 1 << list[i] % 32; if (bitVectorArray[(list[i] - 1)/32][i] & mask == mask) { // print or add list[i] to the result list } else { bitVectorArray[(list[i] - 1)/32] = bitVectorArray[list[i] / 32] | mask; } }
source share