标签:class 二进制 space using span 左移 避免 stream 就会
请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,有2位是1。因此如果输入9,该函数输出2。
一个基本的思路:先判断整数二进制表示中最右边一位是不是1。接着把输入的整数右移一位,此时原来处于从右边数起的第二位被移到最右边了,再判断是不是1。这样每次移动一位,直到整个整数变成0为止。
怎么判断一个整数的最右边是不是1:只要把整数和1做位与运算看结果是不是0就知道了。
int NumberOf1Solution1(int n) { int count = 0; while (n > 0) { if ((n & 1) == 1) { count++; } n = n >> 1; } return count; }
右移运算符m>>n表示把m右移n位。右移n位的时候,最右边的n位将被丢弃。
如果数字原先是一个正数,则右移之后在最左边补n个0;如果数字原先是负数,则右移之后在最左边补n个1。例如下面对两个八位二进制数进行右移操作:
00001010>>2=00000010
10001010>>3=11110001
那么,问题来了:上面的方法如果输入一个负数,比如0x80000000,如果一直做右移运算,最终这个数字就会变成0xFFFFFFFF而陷入死循环。
不右移输入的数字i:
#include <iostream> using namespace std; class Solution { public: int one_count(int n); int num_of_one(int n); }; int Solution::one_count(int n) { unsigned int flag=1;//最大的表示范围 这个解法中循环的次数等于整数二进制的位数,32位的整数需要循环32次。 int sum=0; while(flag) { if(n&flag) ++sum; flag=flag<<1; } return sum; } int Solution::num_of_one(int n) { /* *把一个整数减去1,再和原整数做与运算,会把该整数最右边一个1变成0。 *那么一个整数的二进制表示中有多少个1,就可以进行多少次这样的操作。 */ int sum=0; if(n==0) return 0; while(n) { ++sum; n=n&(n-1);//相当于把二进制最右边的1变成0 } return sum; } int main() { int n; cin>>n; Solution s; cout<<s.one_count(n)<<endl; cout<<s.num_of_one(n)<<endl; return 0; }
标签:class 二进制 space using span 左移 避免 stream 就会
原文地址:https://www.cnblogs.com/tianzeng/p/10146501.html