二进制1的个数

来源:互联网 发布:淘宝培训学校 编辑:程序博客网 时间:2024/05/16 17:11
585  *  二进制的位运算并不是很难掌握,因为位运算总共只有5种运算:与,或,异或,左移,和右移。与,或,和异或运算的规律我们可以用下表总
    结
586  *  与(&)   0 & 0 = 0   1 & 0 = 0   0 & 1 = 0   1 & 1 = 1
587  *  或(|)   0 | 0 = 0   1 | 0 = 1   0 | 1 = 1   1 | 1 = 1
588  *  异或(^) 0 ^ 0 = 0   1 ^ 0 = 1   0 ^ 1 = 1   1 ^ 1 = 0
589  *  左移运算符m<<n表示把m左移n位。左移n位的时候,最左边的n位被丢弃,同时再最最右边补上n个0
590  *  0000 1010 << 2  = 0010 1000
591  *  1000 1010 << 3  = 0101 0000
592  *  右移运算符m>>n表示把m右移n位,右移n位的时候,最右边的n位将被抛弃。但右移时处理最左边位的情形要稍微复杂一些。如果数字时一个右>    符号数值,则用数字的符号位填补最左边的n位。也就是说如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。如果数字原先是一个>    正数,则右移之后再最左边补n个0;如果数字原先是负数,则右移之后再最左边补n个1,
593  *  0000 1010 >> 2 = 0000 0010
594  *  1000 1010 >> 3 = 1111 0001
595  *
596 */
597
598
599  /*
600  *请实现一个函数,输入一个整数,输出该数二进制表示中1的个数。例如把9表示成二进制是1001,右2位是1.因此如果输入9,该函数输出2.
601     解法一:先判断整数二进制表示中最右边一位是不是1.接着把输入的整数右移一位,此时原来处于从右边数起的第二位被移到最右边了,再判>    断是不是1.这样每移动一位,直到整个整数变成0为止。
602
603
604     int Numerof1(int n)
605     {
606         int count = 0;
607         while(n)
608         {
609             if(n & 1)
610                 count++;
611             n = n >> 1;
612         }
613         return count;
614     }
615     这种解法在遇到负数的时候,就会形成死循环。所以并不是最优的解法。

616     常规的解法为:为了避免死循环,我们可以不右移输入的数字n。首先把n和1做与运算,判断n的最低位是不是1.接着把1左移一位得到2,再和n>    做与运算,就能判断n的次低位是不是1,....这样反复左移,每次都能判断n的其中一位是不是1。

   int NumberOf1(int n)
618     {
619         int count = 0;
620         unsigned int flag = 1;
621         while(flag)
622         {
623             if(n & flag)
624                 count++;
625
626             flag = flag>>1;
627         }
628         return count;
629     }
630
631     把一个整数减去1,再和原来的整数做与运算,会把该整数最右边一个1变成0。那么一个整数的二进制表示中有多少个1,就可以进行多少次这>    样的操作。
632     int NumberOf1(int n)
633     {
634         int count = 0;
635
636         while(n)
637         {
638             ++count;
639             n = (n-1) & n;
640         }
641         return coutn;
642     }
643  */
644
645  int main()
646  {
647     int n;
648     cin>>n;
649     cout<<"NumberOf1 = "<<NumberOf1(n)<<endl;
650     return 0;
651  }

原创粉丝点击