算法 – 在O(n)时间内计算2 ^ n

不使用位移,有没有办法在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不一定是任意长度的整数形式.

点赞