问题描述
一元多项式
pn (x) = p0 + p1 x + p2 x 2 + ... + pn x n
在计算机中,可以用一个线性表来表示:
P = (p0, p1, …,pn)
但是对于形如
S(x) = 1 + 3x10000 – 2x20000的多项式,上述表
示方法是否合适?
一般情况下的一元n次多项式可写成
Pn(x) = p1xe1 + p2xe2 + … + pmxem
其中:pi 是指数为ei 的项的非零系数, 0≤ e1 < e2 < … < em = n
可以用下列线性表表示:
((p1, e1), (p2, e2), …, (pm,em) )
例如:P999(x) = 7x3 - 2x12 - 8x999
可用线性表
( (7, 3), (-2, 12), (-8, 999) ) 表示
抽象数据类型一元多项式的定义
我们可以用表来定义一种关于一元(具有非负次幂)多项式的抽象数据类型。
如果大部分系数非零,那么我们可以用一个简单数组来存储这些系数。然后可以编写一些对多项式进行加减乘及其他操作。
ADT Polynomial
{
数据对象:
D={ai|ai∈TermSet,i=1,2,...,m,m>=0 TermSet 中的每个元素包含一个表示系数的实数和表示指数的整数}
数据关系:
R1={<ai-1,ai>|ai-1,ai∈D,且ai-1中的指数值<ai中的指数值,i=2,...,n}
基本操作:
CreatPolyn(&P,m) 操作结果:输入m项的系数和指数,建立一元多项式P。
DestroyPolyn(&P) 初始条件:一元多项式P已存在 操作结果:销毁一元多项式P
PrintPolyn(&P) 初始条件:一元多项式P已存在 操作结果:打印输出一元多项式P
PolynLength(P) 初始条件:一元多项式P已经存在 操作结果:返回一元多项式P中的项数
AddPolyn(&Pa,&Pb) 初始条件:一元多项式Pa和Pb已存在 操作结果:完成多项式相加运算
SubtractPolyn(&Pa,&Pb) 操作结果:完成多项式相减运算
MultiplyPolyn(&Pa,&Pb) 操作结果:完成多项式相乘运算
}ADT Polynomial
代码实现
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE 20/*表可能达到的最大长度,存储空间初始分配量*/
typedef int ElemType;
typedef struct {
ElemType *data;/*数组存储数据元素,最大值为MAXSIZE*/
int highPower;/*最高次项*/
} SqList;
/*操作结果:构造一个空的线性表L*/
void InitList(SqList *L) {
L->data = (ElemType *) malloc(sizeof(ElemType) * MAXSIZE);/*申请连续的MAXSIZE长度空间*/
if (!L->data)/*判断空间是否申请成功*/
exit(-1);
for (int i = 0; i < MAXSIZE; i++)
L->data[i] = 0;
L->highPower = 0;/*空表最高次项为0*/
}
/*初始条件:线性表已存在*/
/*操作结果:销毁线性表L*/
void DestroyList(SqList *L) {
free(L->data);/*释放data指向的空间*/
L->data = NULL;
L->highPower = 0;
}
/*创建多项式:由用户输入多项式的每项系数与指数*/
void CreatePolyn(SqList *L) {
int coefficient, exponent;
for (int i = 0; i < 10; i++)/*循环输入常数项的每一项*/
{
printf("\n请输入第%d项的常数项和指数项,结束请输入-1 -1:", i + 1);
scanf("%d%d", &coefficient, &exponent);
if (exponent != -1) /*指数为-1则结束输入*/
{
L->data[exponent] += coefficient;/*数组下标为指数项,常数项存入下标对应的位置,若有相同指数项则常数项相加*/
if (L->highPower < exponent) /*指数项最大项为多项式长度*/
L->highPower = exponent;
} else
break;
}
printf("输入完毕\n");
}
/*输出常数项:按多项式指数大小依次输出多项式每一项*/
void PrintPolyn(SqList L) {
printf("多项式为:");
if (L.data[0] != 0)/*若常数项为0则不输出,若不为0则只输出常数项*/
printf("%d", L.data[0]);
if (L.data[1] > 0)/*若常数项为0则不输出*/
printf("+%dx", L.data[1]);/*不输出指数项为1*/
else if (L.data[1] < 0)
printf("%dx", L.data[1]);
for (int i = 2; i <= L.highPower; i++)/*从第二项开始输出指数项*/
if (L.data[i] > 0)/*若常数项为0则不输出该项*/
printf("+%dx^%d", L.data[i], i);
else if (L.data[i] < 0)
printf("%dx^%d", L.data[i], i);
printf("\n");
}
/*两多项式相加*/
void AddPolyn(SqList L1, SqList L2, SqList *L3) {
L3->highPower = L1.highPower > L2.highPower ? L1.highPower : L2.highPower;/*获取两多项式的最大项以确定相加后的多项式的最大项*/
for (int i = 0; i <= L3->highPower; i++)/*通过循环将两个多项式的同指数项的系数相加并保存到新的多项式中*/
L3->data[i] = L1.data[i] + L2.data[i];
}
/*两多项式相减*/
void SubtractPolyn(SqList L1, SqList L2, SqList *L3) {
L3->highPower = L1.highPower > L2.highPower ? L1.highPower : L2.highPower;/*获取两多项式的最大项以确定相加后的多项式的最大项*/
for (int i = 0; i <= L3->highPower; i++)/*通过循环将两个多项式的同指数项的系数相减并保存到新的多项式中*/
L3->data[i] = L1.data[i] - L2.data[i];
}
/*两多项式相乘*/
void MuliplyPolyn(SqList L1, SqList L2, SqList *L3) {
L3->highPower = L1.highPower + L2.highPower;/*两多项式的最高项相加为新多项式的最高项*/
for (int i = 0; i <= L1.highPower; i++)
for (int j = 0; j <= L2.highPower; j++)/*通过双层循环将两个多项式的每一项两两相乘与并保存到新的多项式中*/
L3->data[i + j] += L1.data[i] * L2.data[j];/*相乘后的指数项为两项指数项相加*/
}
int main()
{
SqList L1, L2, L3;
InitList(&L1);
InitList(&L2);
InitList(&L3);
printf("\n请输入多项式 1 :");
CreatePolyn(&L1);
printf("\n多项式 1 为:\n");
PrintPolyn(L1);
printf("\n请输入多项式 2 :");
CreatePolyn(&L2);
printf("\n多项式 2 为:\n");
PrintPolyn(L2);
InitList(&L3);
AddPolyn(L1, L2, &L3);
printf("两多项式相加后的结果");
PrintPolyn(L3);
SubtractPolyn(L1, L2, &L3);
printf("两多项式相减后的结果");
PrintPolyn(L3);
DestroyList(&L3);
InitList(&L3);
MuliplyPolyn(L1, L2, &L3);
printf("两多项式相乘后的结果");
PrintPolyn(L3);
return 0;
}