整数的转换成2进制有多少个1

题目:输入一个整数,判断该正数的二进制表示中有多少个1?例如:输入整数12,转换成二进制是1100,共有2个1,因而应该输出2.

 

  分析1:我们可以这样考虑,从右向左注意判断每一个位上是否为1,怎么判断?我们让这个数和整数1(01)做与运算,由于1除最后一位外其余部分全部都是0,因而如果整数的最后一位是1,则返回结果为1,如果整数的最后1为是0,则返回结果为0;接着,我们让该整数与2(10)做与运算,我们就可以判断整数的倒数第二位是否是1;再下来,我们让该整数与4(100)做与运算,判断倒数第三位是否为1;以此类推,我们就可以判断出整数的所有1的个数,而与整数做与运算的数分别为1,2,4,8......我们可以让1做左移1位的运算得到。基于这种思路我们可以得到如下的代码:

复制代码
 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 int NumbersOf1s(int number)
 6 {
 7     int cnt = 0;
 8     unsigned int flag = 1;
 9     while(flag)
10     {
11         if(flag&number)
12             cnt++;
13 
14         flag = flag<<1;
15     }
16     return cnt;
17 }
18 
19 int main()
20 {
21     cout<<"Enter A Number:"<<endl;
22     int i;
23     cin>>i;
24     cout<<"the numbers of 1s in your number is:"
25         <<NumbersOf1s(i)<<endl;
26     return 0;
27 }
复制代码

运行结果如下:

  分析2:如果一个整数不为0,那么它的二进制形式至少有一位是1,如果我们将一个二进制数减去1,那么这个二进制数的最右边的1将会变成0,而这个1后面的0都会变成1.以1100为例,最右边的1是右数第三位,这个数减去1之后变成1011。如果我们把得到的这个数和原数进行与运算,那么右边第一个1及之后的数都为0,即1100&1011==1000,也就是说,我们把一个数减去1后与原数做与运算将会消去最右边的一个1,有多少个1,我们就做多少次类似的循环即可。基于这有思路我们有如下的代码:

复制代码
 1 #include<iostream>
 2 #include<string>
 3 using namespace std;
 4 
 5 int NumbersOf1s(int number)
 6 {
 7     int cnt = 0;
 8     while(number)
 9     {
10         cnt++;
11         number = number & (number - 1);
12     }
13 
14     return cnt;
15 }
16 
17 int main()
18 {
19     cout<<"Enter A Number:"<<endl;
20     int i;
21     cin>>i;
22     cout<<"The Numbers of 1s in your number is:"
23         <<NumbersOf1s(i)<<endl;
24     return 0;
25 }
复制代码

运行结果如下:

  

关于移位运算和乘除运算:在分析1中,我们说可以对一个1不断一位运算得到十进制中的1,2,4,8,16等等,有同学可能会说,我们为什么不对flag做×2的运算呢?因为移位运算的效率要远高于乘除运算,不光是本题,在其他的编程中,我们也应该尽量用移位运算代替乘除运算。

 

 

References:

程序员面试题精选100题:http://zhedahht.blog.163.com/blog/static/2541117420073118945734/

注:

1)本博客所有的代码环境编译均为win7+VC6。所有代码均经过博主上机调试。

2)博主python27对本博客文章享有版权,网络转载请注明出处http://www.cnblogs.com/python27/。对解题思路有任何建议,欢迎在评论中告知。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值