2017-05-05 40 views
0

這裏我有一個二進制字符串,例如 - "01010011"。設置位的位置是= 0, 1, 4, 6(從右到左)。我必須做一系列的操作。如何解除二進制字符串中的第k個設置位

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 
+0

是您的二進制字符串實際文本與「0」和「1」-s?..或者您試圖操縱整數 – Pavel

+0

閱讀您的描述,因爲數字沒有意義。你從最後數到數,然後從開始,你將第0比特再次設置兩次等等。你是否想讓人困惑? – Pavel

+0

我將在C++中使用bitset數據結構。我甚至可以使用整數(例如將二進制字符串轉換爲整數並進行操作) – Atul

回答

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

我會定義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; 
} 
+0

你的'toggleBit'切換第x位,但據我所知,它是關於取消設置那些第n位的問題,即'toggleBit(0001000,1)'應該產生'0000000' – user463035818

+0

hi @ tobi303,嗯,讓我再讀一遍,請注意...... :) –

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頭使用此功能。

相關問題