Python中多项式乘法的朴素递归算法

Python中多项式乘法的朴素递归算法,python,recursion,polynomial-math,polynomials,Python,Recursion,Polynomial Math,Polynomials,我正在尝试实现多项式乘法的分治算法。以下是课堂讲稿中给出的伪代码: 其中,A,B是每个多项式的系数列表,n是问题的大小(度-1),而A_l,B_l是感兴趣系数的指数 下面是我使用Python3实现它的尝试: def poly_mult_dc_naive(A, B, n, a, b): n = int(n) a = int(a) b = int(b) C = [None] * int(2*n - 1) if n == 1: C[0] = A[a] * B[b]

我正在尝试实现多项式乘法的分治算法。以下是课堂讲稿中给出的伪代码:

其中,
A,B
是每个多项式的系数列表,
n
是问题的大小(度-1),而
A_l,B_l
是感兴趣系数的指数

下面是我使用Python3实现它的尝试:

def poly_mult_dc_naive(A, B, n, a, b):
  n = int(n)
  a = int(a)
  b = int(b)
  C = [None] * int(2*n - 1)

  if n == 1:
    C[0] = A[a] * B[b]
    return C[0]

  C[0:n-1] = poly_mult_dc_naive(A, B, n//2, a, b)
  C[n:2*n-1] = poly_mult_dc_naive(A, B, n//2, a + (n // 2), b + (n // 2))

  W = poly_mult_dc_naive(A, B, n/2, a, b + (n // 2))
  V = poly_mult_dc_naive(A, B, n/2, a + n/2, b)
  C[n // 2:n + (n // 2) - 1] += W + V
  return C
然而,我得到了奇怪的结果。例如,让
A=[1,2,3,4]B=[4,3,2,1]
I得到:

[4,无,8,3,6,12,无,16,9,12,2,无,4,1,2,无,8,3,4,无,无]

正确答案是
[4,11,20,30,20,11,4]


有人能指出我哪里出了错,怎么做吗?

快速更新:我想我已经成功地用C的numpy数组而不是列表调试了我的代码。以下是更新版本:

import numpy as np

def poly_mult_dc_naive(A, B, n: int, a: int, b: int):
  C = np.zeros(2*n - 1, dtype=int) # here I changed it from list to np array
  if n == 1:
    C[0] = A[a] * B[b]
    return C[0]
  C[0:n-1] = poly_mult_dc_naive(A, B, n//2, a, b)
  C[n:2*n-1] = poly_mult_dc_naive(A, B, n//2, a + (n // 2), b + (n // 2))
  W = poly_mult_dc_naive(A, B, n//2, a, b + (n // 2))
  V = poly_mult_dc_naive(A, B, n/2, a + (n//2), b)
  C[(n // 2) : (3*n // 2) - 1] += W + V
  return C
附加问题:有谁知道有更好的方法可以将参数n、a和b保持为int类型吗

我只是想写下:

n = int(n)
a = int(a)
b = int(b)
可能不是最优雅的方式

  • 不需要强制将
    n,a,b
    从float转换为int。只需在所有位置使用
    //2
    整数除法(即在W,V行中)。这将把整数“保持”为整数
  • C[n//2:n+(n//2)-1]
    非常需要插入括号,它很容易误读。我会写
    C[(n//2):(3*n//2)-1]
  • 但我郑重建议您使用numpy向量,而不是Python列表。加法、乘法等都是矢量化的

这只是一个关于易读性的提示,为什么不假设n、a、b是整数,因为您使用的是
/2
楼层分割。让调用者负责传递整数参数。告诉我们错误是什么?我看不出你需要强制n,a,b从float到int,只要到处使用
//2
舍入除法(即在W,V行中),它将int保持为int。如果你有一个反例出错,请告诉我们。另外,行
C[n//2:n+(n//2)-1]
非常需要插入括号,它很容易误读。我会写
C[(n//2):(3*n//2)-1]
1。因此,错误在于使用C的列表(即结果系数)会导致在为其切片赋值时出现问题。因此,它会附加值,而不是分配值。将列表更改为numpy数组似乎已经修复了它。你说得对!非常感谢。起初我试过了,但还是有一个错误,但结果我错过了几行的//,而不是/。3.我已按建议把这行加了括号。谢谢你的提示!:)