/** * Return the position of the ii'th 0 bit. This function is implemented using a * binary search on the rank0 function. **/ uint64_t select0(uint64_t const ii) const { uint64_t const i = ii+1; uint64_t left = 0, right = n; while ( (right-left) ) { uint64_t const d = right-left; uint64_t const d2 = d>>1; uint64_t const mid = left + d2; // number of ones is too small if ( rank0(mid) < i ) left = mid+1; // number of ones is too large else if ( rank0(mid) > i ) right = mid; // if this is the leftmost occurence in the interval, return it else if ( (!mid) || (rank0(mid-1) != i) ) return mid; // otherwise, go on and search to the left else right = mid; } return n; }
size_t BitSequenceRRR::select0(size_t i) const { if(i==0) return (uint)-1; if(i>length-ones) return (uint)-1; // Search over partial sums size_t start=0; size_t end=C_sampling_len-1; size_t med, acc=0, pos; while(start<end-1) { med = (start+end)/2; acc = med*sample_rate*BLOCK_SIZE-get_field(C_sampling,C_sampling_field_bits,med); if(acc<i) { if(med==start) break; start=med; } else { if(end==0) break; end = med-1; } } acc = get_field(C_sampling,C_sampling_field_bits,start); while(start<C_len-1 && acc+sample_rate*BLOCK_SIZE==get_field(C_sampling,C_sampling_field_bits,start+1)) { start++; acc +=sample_rate*BLOCK_SIZE; } acc = start*sample_rate*BLOCK_SIZE-acc; pos = (start)*sample_rate; size_t pos_O = get_field(O_pos,O_pos_field_bits,start); // Sequential search over C size_t s = 0; for(; pos<C_len; pos++) { s = get_field(C,C_field_bits,pos); if(acc+BLOCK_SIZE-s>=i) break; pos_O += E->get_log2binomial(BLOCK_SIZE,s); acc += BLOCK_SIZE-s; } pos = (pos)*BLOCK_SIZE; // Search inside the block while(acc<i) { size_t new_posO = pos_O+E->get_log2binomial(BLOCK_SIZE,s); size_t block = E->short_bitmap(s,get_var_field(O,pos_O,new_posO-1)); pos_O = new_posO; new_posO = 0; while(acc<i && new_posO<BLOCK_SIZE) { pos++; new_posO++; acc += (((block&1)==0)?1:0); block = block/2; } } pos--; assert(acc==i); assert(rank0(pos)==i); assert(!access(pos)); return pos; }
unsigned int static_bitsequence::select0(unsigned int i) { if(i>len-ones) return len; if(i==0) return -1; unsigned int ini = 0; unsigned int fin = len-1; while(ini<fin) { unsigned int pos = (ini+fin)/2; unsigned int br = rank0(pos); if(br<i) ini = pos+1; else fin = pos; } return ini; }
size_t BitSequence::select0(const size_t i) const { if (i > length - ones) return -1; if (i == 0) return -1; if (ones == 0) return i - 1; size_t ini = 0; size_t fin = length - 1; while (ini < fin) { size_t pos = (ini + fin) / 2; size_t br = rank0(pos); if (br < i) ini = pos + 1; else fin = pos; } return ini; }
/* * position of i-th bit not set. 0 =< i < rank(size(),0) */ uint64_t select0(uint64_t i){ assert(i<rank0(size())); return spsi_.search_0(i+1); }
/* * total number of bits not set */ uint64_t rank0(){ return rank0(size()); }
/* * number of bits equal to b before position i EXCLUDED */ uint64_t rank(uint64_t i, bool b = true){ return b ? rank1(i) : rank0(i); }
size_t BitSequence::selectPrev0(const size_t i) const { size_t v = rank0(i); if (v < 2) return (size_t) -1; return select0(v - 1); }
size_t BitSequence::selectNext0(const size_t i) const { return select0((i == 0 ? 0 : rank0(i - 1)) + 1); }
size_t rank(bool b, size_t pos) const { if (b) return rank1(pos); return rank0(pos); }
/** * @brief Returns Number of the bits equal to `b` up to position `i` * * @param[in] i Index of the bit vector * @param[in] b Boolean value that indicates bit type.(true = 1, false = 0) * * @return Number of the bits */ FORCE_INLINE uint64_t rank(uint64_t i, bool b = true) const { return b ? rank1(i) : rank0(i); }