剑指 offer:二进制中 1 的个数

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

分析:首先回顾一下补码:对于正数,补码与源码相同,对于负数,符号位取 1,剩下的 31 位(这里默认 int 型整数为 32 位)补码=源码取反+1。已知最高位为符号位,那么剩余 31 位决定正数与负数的大小。正数的最大值+1得到负数的最小值,补码的加减法带上符号位。
对于负数的补码,其二进制 = 2^32 + n(n < 0)。因为对于一个 正数 a,其对应负数 -a 的补码即为a的补数,即 a + (-a)= 2^32 。要理解这句话,需要理解补数,例如,若模为 12,则 8 和 -4 互为补数,5 和 -7 互为补数。在这里,模为 2^32 。互为补数就说明他们都代表着同一个数,只是在不同的进制(在这里为 10 进制)下有不同的表示,对于二进制来说,补数在二进制的表示下是相同的。
下面的代码是按取反加一的规则来的,但准确率 50% 都不到,不知道哪里错了,有知道的兄台麻烦告知一声。

int  NumberOf1(int n) {
	int A[32] = { 0 };
	int flag = 0;
	if (n < 0) {
		flag = 1;
		n = -n;
	}
	int i = 0;
	while (n) {
		A[i++] = n % 2;
		n = n / 2;
	}
	if (flag == 1) {
		A[31] = 1;
		for (int i = 0; i < 31; ++i) {
			A[i] = !A[i];
		}
		A[0] += 1;
		if (A[0] == 2) {
			A[0] = 0;
			for (int i = 1; i < 32; ++i) {
				A[i] += 1;
				if (A[i] == 2) {
					A[i] = 0;
				}
				else {
					break;
				}
			}
		}
	}
	int count = 0;
	for (int i = 0; i < 32; ++i) {
		if (A[i] == 1) {
			count++;
		}
	}
	return count;
}

后来,在牛客网上看到了一种更简单的方法,链接在这里:https://www.nowcoder.com/profile/562667/codeBookDetail?submissionId=1520125

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值