2011-01-16 33 views

Trả lời

18

Hãy thử n & (n-1) nơi &bitwise AND

n = 7 
n - 1 =6 

n & (n-1)=> 0 1 1 1 (7) 
      & 0 1 1 0 (6) 
      --------- 
      0 1 1 0 (done!) 

EDIT (để đáp ứng với những nhận xét được đưa ra bởi Forest)

n = 6 
n - 1 = 5 

n & (n-1)=> 0 1 1 0 (6) 
      & 0 1 0 1 (5) 
      --------- 
      0 1 0 0 (done!) 
+1

@taspeotis: Kiểm tra lại câu hỏi "Làm cách nào để thiết lập ** bên phải ** nhất có thể?" –

+0

Ah, vâng. Tôi bỏ qua từ "set". –

+4

+1 Tuyệt vời! Tôi vẫn không hiểu cách mọi người nhìn thấy các giải pháp như vậy một cách nhanh chóng như vậy. – Dawson

0
unsigned int clr_rm_set_bit(unsigned int n) 
{ 
    unsigned int mask = 1; 
    while(n & mask) { 
     mask <<= 1; 
    } 
    return n & ~mask; 
} 
+1

Đây là O (N) trong khi Prasoon là O (1). Ngoài ra, bạn muốn một cái gì đó giống như 'while (! (N & mask))', nhưng ngay cả điều đó không làm việc cho 'n = 0'. –

+1

Thực ra phương pháp này (khi được triển khai chính xác) không phải là 'O (n)'. Đó là 'O (log (n))'. Và vì n được giới hạn bởi kích thước của một int không dấu, bạn cũng có thể gọi nó là O (1). – Artelius

+0

Phải, nên có giới hạn kiểm tra cho n == 0 và n

4

Câu hỏi của bạn không rõ ràng.

Nếu bạn chỉ muốn unset bit 0, sau đây là một số phương pháp (với các biến thể nhỏ trong hành vi tùy thuộc vào loại của bạn có liên quan):

x &= -2; 
x &= ~1; 
x -= (x&1); 

Nếu bạn muốn bỏ đặt các bit thấp nhất trong số các bit được thiết lập, đây là một số cách sau:

x &= x-1; 
x -= (x&-x); 

Lưu ý rằng x&-x bằng các bit thấp nhất của x, ít nhất là khi x là unsigned hoặc bổ sung twos. Nếu bạn muốn làm bất kỳ số học bit như thế này, bạn chỉ nên sử dụng các loại chưa ký, vì các kiểu đã ký có hành vi được thực hiện theo các hoạt động bitwise.

+5

"bit thiết lập bên phải" có vẻ hoàn toàn rõ ràng. Đó chỉ là một ví dụ được chọn kém. –

Các vấn đề liên quan