取多补少C语言,leetcode题目: 数字的补数 的C语言解法

题目链接

题目内容

给定一个正整数,输出它的补数。补数是对该数的二进制表示取反。

注意:

给定的整数保证在32位带符号整数的范围内。

你可以假定二进制数不包含前导零位。

示例 1:

输入: 5

输出: 2

解释: 5的二进制表示为101(没有前导零位),其补数为010。所以你需要输出2。

示例 2:

输入: 1

输出: 0

解释: 1的二进制表示为1(没有前导零位),其补数为0。所以你需要输出0。

这里先说一下我原先失败的思路:输入测试数据后,将其从十进制转换为二进制,再进入循环判断把各位数的0 1进行置换,求出其补数之后再进行进制转换变成十进制。

最后测试不同的原因也很简单——数值溢出。测试数据稍大一些,转换为二进制占用的空间就越大,这时即使用long int也无法保证存放。最好的方法是设置成字符数组来存放转换过后的二进制数。

通过代码:

int findComplement(int num) {

int comple = 0, i, j = 0, temp;

char result[32] = {0}; // int -- 4 Byte, 4 * 8 = 32 bits

temp = num;

if (num == 1)

return 0;

else {

while (temp) {

i = temp % 2;

result[j++] = i;

temp = temp / 2;

}

while (j > 0) {

i = result[--j];

if (i == 0)

i = 1;

else

i = 0;

comple = i * pow(2, j) + comple;

}

return comple;

}

}

其实这个程序最后的修改部分很考验一个人的基础,倘若能熟练使用数组,也便不会出现直接定义整型数字导致溢出的现象,而且使用字符数组也少了很多不必要的判定条件。

当然这道题的出题目的并不是考这个,它的目的应该是考验对移位,异或的熟练程度。

int findComplement(int num) {

int re = 0, i = 0;

while (num) {

re += ((num % 2) ^ 1) << i++; //所有位数左移

num >>= 1; //num的所有位数向右移一位

}

return re;

}

位移位运算符是将数据看成二进制数,对其进行向左或向右移动若干位的运算。位移位运算符分为左移和右移两种,均为双目运算符。第一运算对象是移位对象,第二个运算对象是所移的二进制位数。

左移: 数值溢出的话丢弃掉最高位,0补最低位

右移:最低位正数补0,负数补1,也就是汇编语言中的算术右移.同样当移动的位数超过类型的长度时,会取余数,然后移动余数个位.

在C中,左移是逻辑/算术左移(两者完全相同),右移是算术右移,会保持符号位不变。

移位其实可以专门写一篇博客了,但我了解和应用并不多,只是参考这别人的介绍大致写了一下规则。以后再碰到类型题可以整理一下。

参考文章:C语言的移位操作符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值