|
@@ -47,10 +47,17 @@ static int getArrayLength(int length, int bits) {
|
|
|
BitArray::BitArray() : length(0), bits(0), data(nullptr) {
|
|
|
}
|
|
|
|
|
|
+static int* allocate(int length, int bits) {
|
|
|
+ int l = getArrayLength(length, bits);
|
|
|
+ int* a = new int[l];
|
|
|
+ memset(a, 0, l * sizeof(int));
|
|
|
+ return a;
|
|
|
+}
|
|
|
+
|
|
|
BitArray::BitArray(int length, int bits)
|
|
|
: length(length), bits(bits), data(nullptr) {
|
|
|
if(length > 0 && bits > 0) {
|
|
|
- data = new int[getArrayLength(length, bits)];
|
|
|
+ data = allocate(length, bits);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -97,6 +104,30 @@ int BitArray::getInternalByteSize() const {
|
|
|
return getArrayLength(length, bits) * sizeof(int);
|
|
|
}
|
|
|
|
|
|
+int BitArray::select(int index) const {
|
|
|
+ if(index <= 0) {
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ int found = 0;
|
|
|
+ int end = getArrayLength(length, bits);
|
|
|
+ for(int i = 0; i < end; i++) {
|
|
|
+ int ones = __builtin_popcount(data[i]);
|
|
|
+ found += ones;
|
|
|
+ if(found >= index) {
|
|
|
+ found -= ones;
|
|
|
+ int a = i * 32 - 1;
|
|
|
+ int d = data[i];
|
|
|
+ while(found < index) {
|
|
|
+ found += d & 1;
|
|
|
+ d >>= 1;
|
|
|
+ a++;
|
|
|
+ }
|
|
|
+ return a;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
void BitArray::fill(int value) {
|
|
|
for(int i = 0; i < length; i++) {
|
|
|
set(i, value);
|
|
@@ -104,7 +135,7 @@ void BitArray::fill(int value) {
|
|
|
}
|
|
|
|
|
|
void BitArray::resize(int newLength, int newBits) {
|
|
|
- int* newData = new int[getArrayLength(newLength, newBits)];
|
|
|
+ int* newData = allocate(newLength, newBits);
|
|
|
int end = Math::min(length, newLength);
|
|
|
for(int i = 0; i < end; i++) {
|
|
|
setBits(newData, i, newBits, get(i));
|