LintCode 1. A+B Problem
两点注意:
1、python不支持空格缩进和TAB缩进混用
2、类内方法调用,不需要再指定self参数
3、python为动态数据类型,不会出现溢出,所以指定数据长度时要进行单独处理
自己的答案:
def myaplusb(a, b):
carry_bit = (a & b) << 1
raw_result = a ^ b
while (carry_bit & raw_result):
temp = carry_bit ^ raw_result
carry_bit = (carry_bit & raw_result) << 1
raw_result = temp
raw_result = carry_bit ^ raw_result
return raw_result
def aplusb(a, b):
if (a < 0) and (b>0):
a = myaplusb(~a, 1)
a = a | 0x80000000
if(abs(a)>b):
sign_result = 1
elif (b < 0) and (a>0):
b = myaplusb(~b, 1)
b = b | 0x80000000
if(abs(b)>a):
sign_result = 1
elif (a<0)and(b<0):
sign_result = 1
else:
sign_result = 0
raw_result = myaplusb(a, b)
result = myaplusb(~raw_result, 1)
result = (result&0x7fffffff) | (sign_result<<31)
return result
虽然想出了异或运算 ^ 做加法,与运算 & 做进位,但是陷入了一个误区,计算机运算是已经是使用二进制补码进行,不需要自己去取反加一,多此一举。
默认补码运算也是为什么会有 ~(-2) 结果为 1的情况。
为了方便,数据长度以8位为例,-2 的反码是1111 1111 1111 1101,补码是1111 1111 1111 1110,取反得到的结果是0000 0000 0000 0001,正数的补码原码一样,所以就会得到1
网上参考答案:
def aplusb(a, b):
# write your code here
while True:
a, b = a^b, (a&b)<<1
if a==0 or b == 0:
return a or b
def aplusb(self, a, b):
#print (a, b)
# write your code here
if b != 0:
return self.aplusb((a^b) & 0xFFFFFFFF, ((a & b) << 1) & 0xFFFFFFFF)
else:
return a if a <= 0x7FFFFFFF else ~(~a & 0xFFFFFFFF)
参考答案有递归和循环两种,递归虽然效率低,但是易读。想了一下,除了刚学编程时,后来做项目工作就从没有写过递归函数。。。感觉好陌生,要不是开始刷题,都忘了这种用法。忘记递归、循环、遍历区别的读者,可以读一下这篇总结循环迭代遍历递归的区别。
参考答案中有一句返回语句,如下,如果a <= 0x7FFFFFFF,则返回a,否则进行取反截位再取反。
return a if a <= 0x7FFFFFFF else ~(~a & 0xFFFFFFFF)
列表生成式一般如下所示,使用for循环和其前面的表达式生成list列表
>>> [x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
#for之后的if做筛选,不能跟else
>>> [x for x in range(1, 11) if x % 2 == 0]
[2, 4, 6, 8, 10]
#for之前的if是表达式,必需跟else
>>> [x if x % 2 == 0 else -x for x in range(1, 11)]
[-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]

浙公网安备 33010602011771号