目标是使用递归计算提升到其他大数字的大数字数字,例如,将100位数字提升到另一个100位数字。
我的计划是递归计算exp / 2,其中exp是指数,并根据exp是偶数还是奇数进行额外的计算。
我目前的代码是:
def power(y, x, n):
#Base Case
if x == 0:
return 1
#If d is even
if (x%2==0):
m = power(y, x//2, n)
#Print statment only used as check
print(x, m)
return m*m
#If d is odd
else:
m = y*power(y, x//2, n)
#Print statement only used as check
print(x, m)
return m*m
我遇到的问题是它进行了太多的计算,而我正在努力弄清楚如何修复它。例如,2 ^ 3返回64,2 ^ 4返回256,2 ^ 5返回1024,依此类推。它计算m * m的次数太多了。
注意:这是解决大数模数的一部分。我正在严格测试代码的指数组件。
答案 0 :(得分:1)
首先,你的实现有一个奇怪的事情:你使用一个你从未使用的参数n
,但只是继续传递而你永远不会修改。
其次第二次递归调用不正确:
else:
m = y*power(y, x//2, n)
#Print statement only used as check
print(x, m)
return m*m
如果你做数学运算,你会看到你返回:(yy x // 2 ) 2 = y 2 *(x // 2 + 1) (请注意//
而不是/
),因此太多了 y 。为了正确地执行此操作,您应该将其重写为:
else:
m = power(y, x//2, n)
#Print statement only used as check
print(x, m)
return y*m*m
(因此从y*
部分移除m
并将其添加到return
语句中,以使其不平方。)
这样做会使您的实现至少在语义上合理。但它无法解决性能/内存问题。
你的comment清楚地表明你想对结果做一个模数,所以这可能是 Project Euler ?
策略是利用模数在乘法下闭合的事实。换句话说,以下是:
(a b)mod c =((a mod c)*(b mod c))mod c
您可以在程序中使用它来防止生成大数字,从而处理需要很少计算工作量的小数字。
另一个优化是你可以简单地在你的论证中使用square。因此,更快的实现类似于:
def power(y, x, n):
if x == 0: #base case
return 1
elif (x%2==0): #x even
return power((y*y)%n,x//2,n)%n
else: #x odd
return (y*power((y*y)%n,x//2,n))%n
如果我们使用此函数进行小测试,我们会发现两个结果对于小数字是相同的(可以在合理的时间/内存中处理pow()
):(12347**2742)%1009
返回{{ 1}}和787L
power(12347,2742,1009)
,因此它们生成相同的结果(当然这不是证明),两者都是等价的,它只是一个简短的结果过滤掉明显错误的测试。
答案 1 :(得分:0)
这是我对这个问题的c版本的处理方法,它适用于正面和负面的曝光:
def power(a,b):
"""this function will raise a to the power b but recursivelly"""
#first of all we need to verify the input
if isinstance(a,(int,float)) and isinstance(b,int):
if a==0:
#to gain time
return 0
if b==0:
return 1
if b >0:
if (b%2==0):
#this will reduce time by 2 when number are even and it just calculate the power of one part and then multiply
if b==2:
return a*a
else:
return power(power(a,b/2),2)
else:
#the main case when the number is odd
return a * power(a, b- 1)
elif not b >0:
#this is for negatives exposents
return 1./float(power(a,-b))
else:
raise TypeError('Argument must be interfer or float')