A smart way to count the ONEs in an integer's binary form representation

There is a smart way to count the ONEs in an integer's binary form representation (this way comes from the book "Beauty of Programming"). Its basic idea is that subtracting ONE from an integer will "change" only the lowest ONE in its binary representation digits. Here "change" means flopping the digits from the lowest ONE to the rest of the lower digits, that is, ONE to ZERO or ZERO to ONE. Take an 8-bit number for example, 00100110 - 1 = 00100101. There are some other examples, 00001000 - 1 = 00000111, 00010111 - 1 = 00010110, etc. Notice that, if we apply an "AND" operation to the integer and the result subtracting one from it, the lowest ONE will be removed. Thus we can add one to the times ONE appears in it. This process is iterated until the "AND" operation produces a ZERO, that is, no ONE is left in the binary form. The iteration times is just the count of ONEs in the integer's binary form. OK, now we can use this more efficient algorithm than testing every bit of the integer to get the count of ONEs appearing in its binary form representation. Below is the implementation.

  1. int numberOfOnes(int n) {
  2.     int num = 0;
  3.     while(n != 0) {
  4.         ++num;
  5.         n &= n - 1;
  6.     }
  7.     return num;
  8. }

Extensively, if we want to know how many different bits there are between two integers A and B, the above algorithm can also be used to reduce the complexity of the overall algorithm. We can first apply an "XOR" operation on A and B, and the result is a new  number whose bits with value ONE is the different bit between A and B. Then we can count the number of ONEs in the "XOR" result to get the number of different bits between A and B. Below is the code.

  1. int numberOfDifference(int a, int b) {
  2.     int c = a ^ b;
  3.     return numberOfOnes(c);
  4. }

Here is a complete test case.

  1. #include <iostream>
  2. using namespace std;
  3. int numberOfOnes(int n);
  4. int numberOfDifference(int a, int b);
  5. int main() {
  6.     int n, k;
  7.     cin >> n;
  8.     k = numberOfOnes(n);
  9.     cout << "n has " << k << " 1s." << endl;
  10.     int a, b;
  11.     cin >> a >> b;
  12.     k = numberOfDifference(a, b);
  13.     cout << "a and b have " << k << " different digits." << endl;
  14.     return 0;
  15. }

You can run it to test any case if you like.

 

Referenced to <Beauty of Programming>.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值