问题很常见:输入为两个一元多项式,要求输出为两个多项式的乘积。例如,输入为2x2+1和5x-1,输出为10x3-2x2+5x-1。
这是我求职期间某家公司的现场编程题。我历来不喜欢为了考试而去拼命做题,使得自己高分低能。而历来我自认为分析解决能力不错,可遇到这道题真是愣住了。当时大概想了下,无非分两步:先将多项式用数据结构表示出来,再去在对数据结构进行运算即可。想到Matlab中多项式的向量表示法,第一步便完成了,第二步便只是对两个向量元素进行数学运算了。
对于一元多项式a0xt+a1xt-1+…+at-1x+at,可将其表示成[a0,a1,…,at-1,at],其中ai对应t阶一元多项式中的aixt-i项。仍然以2x2+1和5x-1为输入,则用向量可将2x2+1表示成[2,0,1],将5x-1表示成[5,-1],其中向量长度为多项式阶次加1,而从第一个元素到最后一个元素对应最高阶到最低阶项的系数,当不存在时系数为0。至此,问题基本已经明了,无非对于两个输入的向量进行某些运算后输出结果向量。
下面用C/C++语言实现一元多项式2x2+1和5x-1的乘法操作。
#include <iostream>
using namespace std;
#define M 3
#define N 2
#define S (M + N - 1)
int main(int argc, char* argv[])
{
int a[M] = {2, 0, 1};
int b[N] = {5, -1};
int c[S] = {0};
// 输出乘法因子
cout<<"输入多项式为:"<<endl;
for (int i=0; i<M; i++)
{
cout<<a[i]<<'/t';
}
cout<<endl;
for (i=0; i<N; i++)
{
cout<<b[i]<<'/t';
}
cout<<endl;
// 进行乘法运算
for (i=0; i<M; i++)
{
for (int j=0; j<N; j++)
{
c[i+j] += a[i] * b[j];
}
}
// 输出乘法结果
cout<<"输出多项式为:"<<endl;
for (i=0; i<S; i++)
{
cout<<c[i]<<'/t';
}
cout<<endl;
return 0;
}
测试如下:
输入多项式为:
2 0 1
5 -1
输出多项式为:
10 -2 5 1
以上仅为一种最简单的直观解法,当多项式的阶次很高但很多项的系数均为0时便是一个稀疏矩阵,多项式向量法的表示造成大量空间浪费。对此,可选用<系数,阶次>的数对来表示多项式中的某项,例如2x2表示为<2,2>,而各项之间用可采用链式结构,在此不再赘述。
事实上,对于一元多项式而言,其组成要素无非各项的系数和对应的阶次问题,向量表示法直接存储系数而将阶次隐含在向量索引中,而链式表示的每个节点则直接存储了这两个因子。在具体应用过程中要根据一元多项式自身的情况选用合适的方法。
遇到陌生的问题并不可怕,可怕的是静不下心来细细思考,而我初次面对这个题便遇到了如此的尴尬,而在走出来后静坐几分钟内又解决了这个问题。很多时候,我们的敌人唯有自己!