zoukankan      html  css  js  c++  java
  • 剑指offer【面试题10:二进制中1 的个数】

    题目:输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

    微机原理基础:

    ①原码表示法规定:用符号位和数值表示带符号数,正数的符号位用“0”表示,负数的符号位用“1”表示,数值部分用二进制形式表示。 
    ②反码表示法规定:正数的反码与原码相同,负数的反码为对该数的原码除符号位外各位取反。 
    ③补码表示法规定:正数的补码与原码相同,负数的补码为对该数的原码除符号位外各位取反,然后在最后一位加1. 
    ④正零和负零的补码相同,[+0]补=[-0]补=0000 0000

    例如: -5

    (一共32位)

    原码:1000 0000 0000 0000 0000 0000 0000 0101 

    反码:1111  1111  1111  1111  1111 1111  1111  1010 (符号位不变,将原码逐位取反)

    补码:1111  1111  1111  1111  1111 1111  1111  1011 (符号位不变,+1)

    对于正数三码一致;我们这里介绍下如何手动计算一个正数的二进制表示。

    比如:7的二进制 0111,计算过程如下,不断处以2,直到商为0。

    另:

    本题输入的是int类型,int类型取值范围:int型为有符号32位整数,占4个字节,取值范围在-2,147,483,648~2,147,483,647之间。

    更多参考:https://blog.csdn.net/q304929130/article/details/48104451

    思路:对于整数,我们直接转成二进制,然后统计1的个数;

               对于0,直接返回0

               对于负数,我们首先得到其绝对值,然后逐位取反(得到反码);最后末位+1(得到补码);我们直接统计0的个数,然后用32去减掉

    【注意:上述有个取绝对值操作,当 输入为: -2,147,483,648的时候,取绝对值是会溢出的,所以这种情况单独处理,具体见代码】

      1 #include<iostream>
      2 #include<vector>
      3 using namespace std;
      4 
      5 // 输入:n:一个int类型的正整数
      6 // 输出:binary:n的二进制表示形式
      7 // 功能:获取一个正整数的二进制
      8 void getBinary(int n, vector<int>& binary)
      9 {
     10      // 初始化
     11     int remainder = n % 2;//余数
     12     int quotient = n / 2;//
     13     binary.push_back(remainder);
     14     while (quotient != 0) //商 = 0则停止计算
     15     {
     16         remainder = quotient % 2;//余数
     17         quotient = quotient / 2;//
     18         binary.push_back(remainder);
     19     }
     20 }
     21 
     22 int  NumberOf1(int n)
     23 {
     24     vector<int> binary;
     25     int count = 0; // 1的个数
     26     // <1> 正数
     27     if ( n > 0)
     28     {
     29         getBinary(n, binary);
     30         for (vector<int>::iterator itr = binary.begin(); itr != binary.end(); itr ++)
     31         {
     32             if (*itr == 1)
     33             {
     34                 count++;
     35             }
     36         }
     37         return count;
     38     }
     39     // <2> 0
     40     else if (n == 0)
     41     {
     42         return count;
     43     }
     44     // <3> 特殊情况
     45     // https://blog.csdn.net/q304929130/article/details/48104451
     46     else if (n == (-2147483648))// int型为有符号32位整数,占4个字节,取值范围在-2,147,483,648~2,147,483,647之间。
     47     {
     48         return 1;
     49     }
     50     // <4> 负数
     51     else
     52     {
     53         int nabs = abs(n);// nabs最大取 ‭01111111111111111111111111111111‬   (2147483647)
     54         //n change to Bianry
     55         vector<int> binary;
     56         getBinary(nabs, binary);
     57         //【计算原码】逐位取反
     58         for (vector<int>::iterator itr = binary.begin(); itr != binary.end(); itr++)
     59         {
     60             if (*itr == 1) 
     61                 *itr = 0;
     62             else
     63                 *itr = 1;
     64         }
     65         // 【计算补码】最后位加1
     66         for (int i = 0; i < binary.size(); i++)
     67         {
     68             //这里有点小技巧
     69             if (binary[i] == 0)
     70             {
     71                 binary[i] = 1;
     72                 break;
     73             }
     74             else
     75             {
     76                 binary[i] = 0;
     77             }
     78         }
     79         // 统计0的个数
     80         for (vector<int>::iterator itr = binary.begin(); itr != binary.end(); itr++)
     81         {
     82             if (*itr == 0)
     83             {
     84                 count++;
     85             }
     86         }
     87         return (32 - count);
     88     }
     89 }
     90 
     91 
     92 int main()
     93 {
     94     cout << "0 = " << NumberOf1(0) << endl;
     95     cout << "3 = " << NumberOf1(3) << endl;
     96     cout << "11 = " << NumberOf1(11) << endl;
     97     cout << "5 = " << NumberOf1(5) << endl;
     98     cout << "7 = " << NumberOf1(7) << endl;
     99     cout << "12 = " << NumberOf1(12) << endl;
    100     cout << "255 = " << NumberOf1(255) << endl;
    101     cout << "-5 = " << NumberOf1(-5) << endl;
    102     cout << "-1 = " << NumberOf1(-1) << endl;// 2 应该是32
    103     cout << "-127 = " << NumberOf1(-127) << endl; // -2147483648
    104     cout << "-2147483648 = " << NumberOf1(-2147483648) << endl; // 1
    105     return 1;
    106 }

    例如:我们通过计算器来验证, 猜测:由于我们是64位系统,这里显示出来是64位;在本题,我们默认是32位系统。

    我们看到有一个0;所以 32 - 1 = 31(符合上述代码计算结果。)

    同理:32 - 6 = 26;

    同理:32 - 31 = 1;

  • 相关阅读:
    (22)进程和线程区别
    (21)回调函数
    (20)gevent协程
    (18)ProcessPoolExecutor进程池
    (19)ThreadPoolExecutor线程池
    (17)线程队列---queue LifoQueue PriorityQueue
    (16)线程---定时器Timer
    (15)线程---Condition条件
    (14)线程- Event事件和守护线程Daemon
    IDEA快速搭建WEB项目【记录篇】
  • 原文地址:https://www.cnblogs.com/winslam/p/9476972.html
Copyright © 2011-2022 走看看