0

Here i have a binary string, for example - "01010011". The positions of set bits are = 0, 1, 4, 6 (from right to left). I have to do series of operations something like this.

for binary string - 01010011
unset the 0th set bit. - 01010010 (new set bit positions - 1, 4, 6)
unset the 0th set bit  - 01010000 (new set bit positions - 4, 6)
unset the 1st set bit -  00010000 (new set bit positions - 4)

As you can see after each operation my binary string changes and the new operations should be done on that.

My approach was to make a copy of binary string and loop through k-1 times and unset the rightmost set bit. after k-1 loop, my rightmost set bit will be the actual kth bit and i can get the position of this and unset this position in my original binary. But this method looks very inefficient to me.

I need some efficient approaches and c/c++(bitset) or python code is highly appreciated.

Note:

The kth bit will be always set in my binary string
Atul
  • 546
  • 4
  • 16
  • is your binary string actual text with "0" and "1"-s?.. or you are trying to manipulate integers – Pavel P May 05 '17 at 06:21
  • read your descriptions, as numbers no not make sense. You count bits from end, then from start, you unset 0th bit twice etc. Are you trying to make people confused? – Pavel P May 05 '17 at 06:23
  • I will be using bitset data structure in c++. I can even use integers too(like converting the binary string to integer and doing the set of operations) – Atul May 05 '17 at 06:24
  • \@Pavel it is counted from right to left. – Atul May 05 '17 at 06:28
  • 1
    @Pavel OP is counting the non zero bits starting from the "right" and doing operation only on those. – Bob__ May 05 '17 at 06:29

3 Answers3

1

If you use bitset then you can loop and find first rightmost set bit, with regular integer it can be done this way:

unsigned i, N = ...;
for (i=0; i<sizeof(unsigned)*8; ++i)
{
    if (N & (1<<i))
        break;
}

i at this point should contain index of your first rightmost set bit in your N.

Also, on most CPUs there are dedicated instructions to count leading zeros etc to count leading zeros, or trailing bits.

How do i unset the kth set bit in binary string?

unsigned i, N = ..., k = ... ; // where k is [1..32] for 32-bit unsigned int
for (i=0; i<sizeof(unsigned)*8; ++i)
{
    if (N & (1<<i))
    {
        if (--k == 0)
        {
            N &= ~(1<<i) // unset k-th set bit in N
            break;
        }
    }
}
Pavel P
  • 15,789
  • 11
  • 79
  • 128
1

I would define 3 functions to handle that using string.lenght

void setBit(string& t, const int x);
void clearBit(string& t, const int x);
void toggleBit(string& t, const int x);

the implementation could look like

void setBit(string& t,const int x) {
    t[t.length()-1-x] = '1';
    cout << "new val: " << t << endl;
}

void clearBit(string& t, const int x) {
    t[t.length() - 1 - x] = '0';
    cout << "new val: " << t << endl;
}

void toggleBit(string& t, const int x) {
    char d = t[t.length() - 1 - x];
    if (d=='0')
    {
        setBit(t, x);
    }
    else {
        clearBit(t, x);
    }
}

and test it like:

int main(int argc, char** argv)
{
    string test = "01010011";
    setBit(test, 0);
    clearBit(test, 0);
    toggleBit(test, 2);
    toggleBit(test, 2);

    return 0;
}
ΦXocę 웃 Пepeúpa ツ
  • 47,427
  • 17
  • 69
  • 97
0

How about using lambda as following. I define a function which requires reference of your bit string and the k-th set bit.

void unset_kth(std::string& bit, const size_t k) {
  size_t found = 0;
  std::reverse(bit.begin(), bit.end());
  std::replace_if(bit.begin(), bit.end(),
      [&found, k](char letter) -> bool {
        if(letter == '1') {
          if (found == k) {
            found++;
            return true;
          } else {
            found++;
          }
        }
        return false;
      }, '0');
  std::reverse(bit.begin(), bit.end());
}

and use this function as you wish

std::string bit = "01010011";
unset_kth(bit, 0);  // 01010010
unset_kth(bit, 1);  // 01010000
unset_kth(bit, 1);  // 00010000

This code needs string and algorithm header.