对于一个多项式,需要处理的数据有每一项的幂级数,以及该项的系数。
1. 数组实现
这是比较简单的一种方法,先看多项式的数据结构:
typedef struct _polynomial
{
int high_power;
/* +1 because there is constant term. */
int coff_array[MAX_DEGREE + 1];
} *Polynomial;
在上述数据结构中:
- high_power是该多项式的最高项的次数;
- coff_array是系数数组,且下标对应次数
有了上面的数据结构,多项式的加法、减法、乘法都可以一一实现了,伪代码如下:
add_polynomial(poly1, poly2, poly_sum):
max_power = max{poly1.high_power, poly2.high_power}.
for i from 0 to max_power:
poly_sum.coff_array[i] =
poly2.coff_array[i] + poly1.coff_array[i]
multi_polynomial(poly1, poly2, poly_prod):
for i from 0 to poly1.high_power:
for j from 0 to poly2.high_power:
poly_sum.coff_array[i * j] +=
poly1.coff_array[i] * poly2.coff_array[j]
因为减法与加法几乎完全一样,不再赘述。
可以注意到的是,由于使用下标作为系数,所以无法表示
2
2
3
2^{\frac{2}{3}}
232一类的项。这也是无法实现除法的主要原因。
算法复杂度:
add_polynomial()
从0
遍历到high_power
,取决于两个poly
中较大的high_power
。
multi_polynomail()
两重遍历,都是从0
遍历到high_power
,为
O
(
m
n
)
O(mn)
O(mn),其中
m
m
m与
n
n
n分别是两个乘数多项式的最高次幂。
2. 链表实现
除了不能使用除法,数组实现还有一些小的问题,比如有最高次幂的限制。最重要的一点是,如果多项式的大多数次幂的系数都为0,即coff_array
中的大多数元素值都为0,那么在系数为0的数据上会花费很多时间。比如
p
1
=
x
2001
+
7
x
1000
+
5
p_1 = x^{2001} + 7x^{1000} + 5
p1=x2001+7x1000+5,
p
2
=
10
x
2308
+
66
p_2 = 10x^{2308} + 66
p2=10x2308+66,那么
p
1
×
p
2
p_1 \times p_2
p1×p2的计算过程中会有大量的
0
×
0
0 \times 0
0×0的操作。
如果采用链表的方式,那么上述问题都可以解决了,先来看一下节点的数据结构:
typedef struct Node *Ptr_Node;
typedef Ptr_Node Polynomial;
typedef Polynomial List;
struct Node
{
int coffient;
int degree;
Ptr_Node next_node;
};
其中coffient
表示当前节点的系数,degree
表示当前节点的次幂。然后加法和乘法的伪代码如下所示:
add_polynomial(poly1, poly2, poly_sum):
for n1 in poly1 and n2 in poly2:
if n1.degree < n2.degree:
poly_sum.append(n1)
n1 = n2->next
else if n1.degree > n2.degreee:
poly_sum.append(n2)
n2 = n2.next
else if n1.degree == n2.degree:
n3.degree = n1.degree
n3.coffient = n1.coffient + n2.coffient
poly_sum.append(n3)
n1 = n1.next
n2 = n2.next
multi_polynomail(poly1, poly2, poly_prod):
for n1 in poly1:
for n2 in poly2:
n3.degree = n1.degree + n2.degreee
n3.coffient = n1.coffient * n2.coffient
for np in prod:
if np.degree == n3.degree:
np.coffient += ne.coffient
if didn't find np.degree = n3.degree:
insert n3 to appropriate position of poly_prod
减法与除法依旧是与加法和乘法类似的操作,不再赘述。
算法复杂度:
add_polynomial()
复杂度为
O
(
m
+
n
)
O(m + n)
O(m+n),其中
m
m
m与
n
n
n分别是两个加数多项式项的个数,一般多数情况下,多项式个数小于最高次幂。
multi_polynomial()
外部是两层循环,复杂度为
O
(
m
n
)
O(mn)
O(mn);内部的for
循环次数从1
开始,最多增长到m * n
,复杂度为
1
+
2
+
3
+
.
.
+
m
n
=
∑
i
=
1
m
n
i
=
m
n
(
m
n
+
1
)
2
=
O
(
m
2
n
2
)
1 + 2 + 3 + .. + mn = \sum_{i=1}^{mn}{i} = \frac{mn(mn + 1)}{2} = O(m^2n^2)
1+2+3+..+mn=i=1∑mni=2mn(mn+1)=O(m2n2)
所以总的时间复杂度为
O
(
m
3
n
3
)
O(m^3n^3)
O(m3n3)。
乘法的复杂度感觉算得有点问题,如果有哪位大佬能算出准确界,还望告知。