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

题目描述

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

这道题主要考察大家对一个数在计算机中的二进制表示形式的理解,比较基础,但是也是大家比较容易忽视的地方;因此,需要再巩固一下细节。

一个数在计算机中的二进制表示形式,  叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1
原码:原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值.
比如8位二进制1,-1的原码如下
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:
[1111 1111 , 0111 1111]

[-127 , 127]
反码:正数的反码是其本身,负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反
补码:正数的补码就是其本身,负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)


求解这道题,我采用的数据结构是堆栈,用两个堆栈实现原码、反码及步码的转换,具体细节看代码

class Solution {
public:
     int  NumberOf1(int n) {
         if (n == 0)
         {
             return 0;
         }
         stack<int> s1;
         stack<int> s2;
         bool flag = false;
         int temp = 0;
         int counter = 0;
         if (n < 0)
         {
             flag = true;
             n = abs(n);
         }
         
         while (n)
         {
             s1.push(n % 2);
             if (!flag && n % 2 == 1)
             {
                 temp++;
             }
             n = n / 2;
             counter++;
         }
         while (counter < 31)
         {
             s1.push(0);
             counter++;
         }
         if (!flag)
         {
             return temp;
         }
         int st = 0;
         while (!s1.empty())
         {
             if (s1.top() == 1)
             {
                 s2.push(0);
                 
             }
             else if (s1.top() == 0)
             {
                 s2.push(1);
             }
             s1.pop();
         }
         int carry = 1;
         while (!s2.empty())
         {
             if (s2.top() + carry == 2)
             {
                 s1.push(0);
                 carry = 1;
             }
             else if (s2.top() + carry == 1)
             {
                 s1.push(1);
                 temp++;
                 carry = 0;
             }
             else
             {
                 s1.push(0);
                 carry = 0;
             }
             s2.pop();
         }
         return temp+1;
     }
};

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值