我如何在二进制字符串中解开KTH集位

How do i unset the kth set bit in binary string

本文关键字:KTH 集位 字符串 二进制      更新时间:2023-10-16

在这里我有一个二进制字符串,例如- "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循环之后,我的最右侧位将是实际的KTH位,我可以得到这个位置,并在我的原始二进制中弄清此位置。但是这种方法对我来说效率很低。

我需要一些有效的方法,并且高度赞赏C/C (bitset(或Python代码。

注意:

The kth bit will be always set in my binary string

我将定义3个函数以使用string.lenght

处理该功能
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;
}

如果您使用bitset,则可以循环并找到第一个右设置位,使用常规整数可以这样做:

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

i此时应包含N中最右的索引。

此外,在大多数CPU上,都有专门的说明来计算领先的零等待以计数领先的零或尾随位。

如何在二进制字符串中解开kth集合?

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

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

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标头。