不使用位移,有没有办法在O(n)时间内计算2 ^ n?
我正在考虑使用memoization的解决方案,因为我将始终从较低的n开始计算.
即
d = dict()
def pwr2(n):
if n == 0:
return 1
if n == 1:
return 2
if n in d:
return d[n]
d[n] = 2 * pwr2(n-1)
return d[n]
但我不太清楚复杂性会是什么.
编辑:我应该补充一点,我使用这个算法的一部分,以比O(n ^ 2)时间更快的速度将二进制转换为十进制.作为我的分而治之算法的一部分,我必须乘以增加2的幂,因此我尝试记忆.
EDIT2:只需在此处发布我的完整算法,以帮助解决混乱
pwr2dict = dict()
def karatsuba(x, y):
// use karatsuba's algorithm to multiply x*y
def pwr2(n):
if n == 0:
return 1
if n == 1:
return 2
if n in pwr2dict:
return pwr2dict[n]
pwr2dict[n] = karatsuba(pwr2(n-1),2)
return pwr2dict[n]
def binToDec(b):
if len(b) == 1:
return int(b)
n = int(math.floor(len(b)/2))
top = binToDec(b[:n]) # The top n bits
bottom = binToDec(b[n:]) # The bottom n bits
return bottom + karatsuba(top, pwr2(len(b)-n))
print binToDec("10110") // Prints 22
最佳答案 我认为你是在思考你的问题. 2 ^ n简单地意味着将n与自身相乘n次.所以从1到n的简单循环将起到作用:-)
r = 2
for 1 to n do
r = r * 2
end
这是在O(n)中运行的解决方案,计算2 ^ n的真正问题是,在现代计算机上,你会在体系结构的字长上找到相当小的n,如32,64或128.然后你有使用一个任意长度的整数,这可能不会给你很长的O(n)时间,但这是一个不同的问题:-)理论上,它可以在O(n)中完成.
编辑
好的,所以如果我理解正确你有一个很长的二进制字符串,并且你想将它转换为十进制.
我将实现如下:
将长度为n的二进制字符串放入一个数组中,s(可以是位图以节省空间,可以是支持这些字符串的编程语言中的字符串).反转字符串,使LSB处于索引0(如果不是这种情况).
e := 1
r := 0
for i := 0 to (n - 1)
if s[i] = 1
r := r + e
end
e := e * 2
end
反转字符串可以在O(n)中完成,伪代码只有一个从0到n – 1的循环,所以在O(n)中也是如此.位串反转可以避免在循环中进行简单的算术运算.而且r不一定是任意长度的整数形式.