评估多项式系数

3
我正在尝试编写一个函数,它以多项式p(x)的系数列表(a0、a1、a2、a3......an)和值x作为输入。该函数将返回p(x),即在x处求值时的多项式值。
具有系数a0、a1、a2、a3......an的n次多项式是以下函数:
p(x)= a0+a1*x+a2*x^2+a3*x^3+.....+an*x^n

我不确定如何解决这个问题。我想我需要一个范围,但是如何使其能够处理任何数字输入的x?我不指望你们给出答案,我只需要一点启动帮助。我需要使用for循环、while循环还是递归可能是一个选项?

def poly(lst, x)

我需要遍历列表中的项目,我该使用索引,但如何使其遍历未知数量的项目?

我想我可以在这里使用递归:

    def poly(lst, x):
        n = len(lst)
        If n==4:
           return lst[o]+lst[1]*x+lst[2]*x**2+lst[3]*x**3
        elif n==3:
           return lst[o]+lst[1]*x+lst[2]*x**2
        elif n==2:
           return lst[o]+lst[1]*x
        elif n==1:
           return lst[o]
        else:
            return lst[o]+lst[1]*x+lst[2]*x**2+lst[3]*x**3+lst[n]*x**n

这个代码在n<=4的情况下可以正常运行,但是当n>4时会出现索引错误:list index out of range。不过我不知道原因。


2
提示:查找sumenumerate的含义。(PS: 别忘了在 Python 中我们使用 ** 而不是 ^ 来进行乘幂运算,即 x*x = x**2。) - DSM
我知道sum是什么,但是让我困惑的是如何编写代码,使得n值被纳入其中。 - Snarre
@Snarre 看看我的回答,我认为那就是你想要的。 - Rushy Panchal
“enumerate” 就在那里等着你。查一下它的作用,这对你为每个系数创建 n 应该有所帮助。 - Sukrit Kalra
@回答者们:由于 OP 要求根据 x 和系数输入 任何数值,因此在进行求和时,人们可能希望使用调整的排序以避免失去太多精度。 - Benjamin Bannier
5个回答

9

最有效的方法是使用霍纳规则反向求解多项式。在Python中非常容易实现:

# Evaluate a polynomial in reverse order using Horner's Rule,
# for example: a3*x^3+a2*x^2+a1*x+a0 = ((a3*x+a2)x+a1)x+a0
def poly(lst, x):
    total = 0
    for a in reversed(lst):
        total = total*x+a
    return total

2
def evalPoly(lst, x):
    total = 0
    for power, coeff in enumerate(lst): # starts at 0 by default
        total += (x**power) * coeff
    return total

或者你可以使用列表,然后使用 sum

def evalPoly(lst, x):
        total = []
        for power, coeff in enumerate(lst):
            total.append((x**power) * coeff)
        return sum(total)

不使用枚举:

def evalPoly(lst, x):
    total, power = 0, 0
    for coeff in lst:
        total += (x**power) * coeff
        power += 1
    return total

非枚举方法的替代方案:

def evalPoly(lst, x):
    total = 0
    for power in range(len(lst)):
        total += (x**power) * lst[power] # lst[power] is the coefficient
    return total

此外,@DSM提到,您可以将此内容组合成一行代码:
def evalPoly(lst, x):
    return sum((x**power) * coeff for power, coeff in enumerate(lst))

或者使用lambda

evalPoly = lambda lst, x: sum((x**power) * coeff for power, coeff in enumerate(lst))

递归解法:

def evalPoly(lst, x, power = 0):
    if power == len(lst): return (x**power) * lst[power]
    return ((x**power) * lst[power]) + evalPoly(lst, x, power + 1)

enumerate(iterable, start)是一个生成器表达式(因此使用yield而不是return),它产生一个数字和可迭代对象的元素。该数字等同于该元素的索引+起始值。

根据Python文档,它与以下内容相同:

def enumerate(sequence, start=0):
    n = start
    for elem in sequence:
        yield n, elem
        n += 1

是的,它可以运行,但我们在课堂上还没有讲解enumerate,所以我不确定它为什么或者如何运作。 - Snarre
(1) 我觉得你不想从1开始。OP的第一个术语是a0*x**0。(2)我们可以将整个内容压缩为sum(coeff*x**i for i, coeff in enumerate(lst)) - DSM
既然我们还没有在课堂上使用enumerate或lambda,我认为我需要坚持使用索引。但是让我困惑的是,在你们的代码中,函数p(x)= a0+a1x+a2x^2+a3x^3+.....+anx^n在哪里呢? - Snarre
@Snarre 这个来自于 for 循环。for power, coeff in enumerate(lst) 会从0和a0开始,接着是1和a1。a0和a1是在 lst 中提供的系数,而0和1则是由 enumerate 函数提供的幂。 - Rushy Panchal
@Snarre 看看我的新编辑。for coeff in lst 从列表中提取系数(由用户提供),而 power 只是一个你递增的变量。 - Rushy Panchal
显示剩余2条评论

2

简单:

def poly(lst, x): 
  n, tmp = 0, 0
  for a in lst:
    tmp = tmp + (a * (x**n))
    n += 1
return tmp print poly([1,2,3], 2)

简单递归:

def poly(lst, x, i = 0):
  try:
    tmp = lst.pop(0)
  except IndexError:
    return 0
  return tmp * (x ** (i)) + poly(lst, x, i+1)

print poly([1,2,3], 2)

2
使用enumerate比保留索引i要容易得多。 - James
@Imagine 是的,看起来是这样。我不知道这件事。 - Yura Beznos
@Snarre lst.pop(0) 是你列表中的第一个元素,即“a0”。 - Yura Beznos
@Snarre,你在这里不需要递归。而且这也不是一个递归。 - Yura Beznos
好的,我写了一个递归替代方案(添加了),它部分地起作用,当n>4时我遇到了一个索引错误...不过我不知道为什么。 - Snarre
显示剩余6条评论

1
无论是递归还是非递归,解决方案的本质都是在“n”上创建一个循环,因为多项式从x^0开始,并上升到a_n.x^n,这也是您应该考虑的变量。除此之外,使用称为乘法累加的技巧,以便能够在每个循环迭代中计算部分结果。

0
def evalPoly(lst, x, power):
    if power == 0:
        return lst[power]
    return ((x**power) * lst[power]) + evalPoly(lst, x, power - 1)

lst = [7, 1, 2, 3]
x = 5
print(evalPoly(lst, x, 3))

需要求解的方程为 - 3x^3 + 2x^2 + x + 7 当 x = 5 时,结果为 - 437


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接