我以前的问题(现在已解决)是:
作为输入,我有一个非负整数列表,它应该是多项式的系数。但我也想评估一个数x的多项式。
例如:
如果我们将L=[2,3,1]
作为输入,x=42
我们会得到2x^2+3x+1=3655
我想要的是例如:
>>>p=polynomial([2,3,1])
>>>p(O)
1
>>>p(42)
>>>3655
代码是
def polynomial(coef):
def poly(x):
result = 0
x_n = 1
for a in reversed(coef):
result += a * x_n
x_n *= x
return result
return poly
我现在要做的是找到逆,这意味着输入是单调多项式和正整数y,我想找到整数x,使得p(x)= y,和x应仅在[1,10 ** 10]中,例如:
>>>p=polynomial([2,3,1])
>>>p(O)
1
>>>p(42)
>>>3655
>>>invert(3655,p)
42
这是我到目前为止所做的,但我得到的是运行时错误:
def polynomial(coef):
def poly(x):
result = 0
xn = 1
for c in reversed(coef):
result += c * xn
xn *= x
return result
return poly
def invert(y,p):
test=10**10
if p(2)>p(1):
if p(test)>y:
test=test//2 +(test%2)
return invert(y,p)
elif p(test)<y:
test=test+(test//2)
return invert(y,p)
else:
return test
if p(2)<p(1):
if p(test)<y:
test=test//2 +(test%2)
return invert(y,p)
elif p(test)>y:
test=test+(test//2)
return invert(y,p)
else:
return test
发生的错误是
...
File "poly.py", line 17, in invert
return invert(y,p)
File "poly.py", line 14, in invert
if p(2)>p(1):
File "poly.py", line 5, in poly
for c in reversed(coef):
RuntimeError: maximum recursion depth exceeded while calling a Python object
我做错了什么?
答案 0 :(得分:3)
您的invert
函数永远会递归,因为您永远不会修改传递给下一个调用的参数。您确实修改了test
,但这对您没有任何好处,因为内部调用将拥有自己的test
副本。
有几种方法可以解决问题。您可以将test
作为参数传递给invert
函数,初始值为默认值,将在第一次使用:
def invert(y, p, test=10**10):
# ...
# later, when you recurse:
test = test // 2 # or whatever
return invert(y, p, test) # pass on the modified test value
另一种(可能更好的)方法是放弃递归,而是使用循环。 while
循环似乎在这里是合适的:
def invert(y, p):
test = 10**10
sign = (-1)**(p(2) < p(1))
while True:
if p(test) > y:
test -= sign * (test // 2)
elif p(test) < y:
test += sign * (test // 2)
else:
return test # this is the only case that returns
我让整个算法与你原来的代码一样(只是精简了一点)。如果您的多项式没有严格增加或严格减少,那么该算法可能不正确。你应该在test
计算多项式的导数,以确定要调整的方向,但我会留给你弄清楚。
答案 1 :(得分:1)
我冒昧地修复了你发布的代码的缩进。 请确认以下代码实际上是关于缩进的代码以下代码确实会返回您想要的输出..
def polynomial(coef):
def poly(x):
result = 0
x_n = 1
for a in reversed(coef):
result += a * x_n
x_n *= x
return result
return poly
def invert(y,p,test): # updated
# test=10**10 # This was the problem
# You reset 'test' for every recursive call
# which means you will stand still without
# any progress until the max num of allowed
# recursive calls are reached.
if p(2)>p(1):
if p(test)>y:
test=test//2 +(test%2)
return invert(y,p,test) # updated
elif p(test)<y:
test=test+(test//2)
return invert(y,p,test) # updated
else:
return test
if p(2)<p(1):
if p(test)<y:
test=test//2 +(test%2)
return invert(y,p,test) # updated
elif p(test)>y:
test=test+(test//2)
return invert(y,p,test) # updated
else:
return test
p = polynomial([2,3,1])
t = 10**10
print(invert(3655,p,t))
答案 2 :(得分:0)
我现在自己编写代码,将所有内容限制在我迄今为止所拥有的知识/技能中,并且有效:
def polynomial(coef):
def poly(x):
result = 0
x_n = 1
for a in reversed(coef):
result += a * x_n
x_n *= x
return result
return poly
def invert(y,p):
x=10**10
while p(x)!=y:
if p(x)>y:
w=x
x=x//2
elif p(x)<y:
x=(x+w)//2
return x