如何取消设置二进制字符串

时间:2017-05-05 06:16:35

标签: c++ bit-manipulation bitset

这里我有一个二进制字符串,例如 - "01010011"。设置位的位置是= 0, 1, 4, 6(从右到左)。我必须做一系列类似的操作。

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)

正如您在每次操作后看到的那样,我的二进制字符串会发生变化,并且应该对其进行新的操作。

我的方法是复制二进制字符串并循环k-1次并取消设置最右边的设置位。在k-1循环之后,我最右边的设置位将是实际的第k位,我可以得到它的位置并在我的原始二进制中取消设置这个位置。但这种方法对我来说效率很低。

我需要一些有效的方法和c / c ++(bitset)或python代码非常受欢迎。

注意:

The kth bit will be always set in my binary string

3 个答案:

答案 0 :(得分:1)

如果使用bitset,那么你可以循环找到第一个最右边的设置位,使用常规整数可以这样做:

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

i应包含N中第一个最右边设置位的索引。

此外,在大多数CPU上都有专用指令来计算前导零等,以计算前导零或尾随位。

  

如何取消设置二进制字符串中的第k个设置位?

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;
        }
    }
}

答案 1 :(得分:1)

我将使用string.lenght

定义3个函数来处理它
void setBit(string& t, const int x);
void clearBit(string& t, const int x);
void toggleBit(string& t, const int x);

实施可能看起来像

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);
    }
}

并测试它:

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

    return 0;
}

答案 2 :(得分:0)

如何使用lambda如下。我定义了一个函数,需要引用你的bit字符串和k设置位。

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());
}

并根据需要使用此功能

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

此代码需要stringalgorithm标题。