当着手于多项式加法的实现,线性表就成为了实现目标的工具,要对工具进行保护,实际就是对工具进行一次封装,例如:
void destoryPoly(POLY **head) {
return destoryLinear(head);
}
实际destoryPoly和destoryLinear是相同的,表面只是重新给个名字,在实际程序中,线性表作为最基础的工具,我们用.o来保护,只给一个.h来提示可用的函数。
在多项式实现中,LINEAR原本表示控制头,指向线性表, 实际问题中,POLY表示控制头,指向多项式,所以:
typedef LINEAR POLY;
进行一次def达到该目的。
进行多项式实现,数据类型也有了具体的形式,对于一个单项式来说,数据有系数和指数,即:
typedef struct POLY_ITEM {
double coefficient;
int power;
}POLY_ITEM, USER_TYPE;
所需要的数据都定义完,就该进行初始化了:
初始化多项式:
在多项式初始化过程中,我们返回线性表的初始化,每一次的封装实际就是根据实际问题对工具进行加工,那么初始化工具有data,capacity,count,equals。
在多项式问题中,数据的USER_TYPE已经处理完成,接下来equals在多项式中,不需要相等的对比,只需要进行指数大小的比较,即:
int comparePolyItem(POLY_ITEM one, POLY_ITEM other) {
return one.power - other.power;
}
比较函数定义好,就应在初始化中赋值了:
boolean eqPolyItem(POLY_ITEM one, POLY_ITEM other) {
return comparePolyItem(one, other) == 0;
}
boolean initPoly(POLY **poly, int capacity) {
boolean ok = initLinear(poly, capacity);
if (ok) {
setEquals(*poly, eqPolyItem);
}
return TRUE;
}
初始化结束后,就应该开始输入数据了:
输入多项式:
输入多项式就是在数据合理的情况下,在多项式末尾追加:
while (fabs(coefficient) > 1e-6) {
data.coefficient = coefficient;
data.power = power;
appendPolyItem(head, data);
printf("coefficient:");
scanf("%lg", &coefficient);
printf("power:");
scanf("%d", &power);
}
摧毁,追加都是在工具的基础上进行封装即可:
void destoryPoly(POLY **head) {
return destoryLinear(head);
}
boolean appendPolyItem(POLY *head, POLY_ITEM data) {
return appendElement(head, data);
}
打印多项式:
类似于这种打印数据的问题,我们可以分开,由打印一个单项式,通过循环达到打印多项式的做法
那么我们首先要做到打印一个单项式:
首先,对于符号位:
对指数的思考: 若指数为0,不需要输出x,直接输出系数即可, 指数为1,输出x,指数大于1,输出x^指数
对系数的思考:因为计算机输出普通的正数是不会有正号的,对于第一项,系数大于0,不需要输出正号,系数小于0,输出负号;
但是对于其余项,系数大于零需要输出正号来表示加号;系数等于1,只输出正号;系数等于-1,只输出负号。
所以我们需要的参数有这个项,以及是否是第一项。
即:
void printItem(const POLY_ITEM data, boolean isFirst) {
if (!isFirst && data.coefficient > 1e-6) {
printf("+");
}
if (data.power == 0) {
printf("%lg", data.coefficient);
} else if (fabs(data.coefficient - 1) < 1e-6) {
;
} else if (fabs(data.coefficient + 1) < 1e-6) {
printf("-");
} else {
printf("%lg", data.coefficient);
}
if (data.power > 1) {
printf("x^%d", data.power);
} else if (data.power == 1) {
printf("x");
}
}
实现输出一项之后,输出整个多项式就是遍历循环输出即可:
void printPoly(const POLY *head) {
int index;
int count;
POLY_ITEM item;
if (NULL == head || isPolyEmpty(head)) {
return ;
}
count = getItemCount(head);
for (index = 0; index < count; index++) {
getItemAt(head, index, &item);
printItem(item, index == 0);
}
}
多项式相加:
多项式相加的逻辑:因为我们所获得的多项式都是从高次降序排到低次,所以从两个多项式各取一项,比较他的指数,指数大的说明没有与之匹配的项,直接追加到结果多项式即可,若指数相等,则对系数进行相加运算。
当有一个多项式遍历完,说明另一多项式剩下的项没有所匹配的,不用进行计算,直接追加到结果即可,但我们无法知道是哪个多项式先遍历完成,所以要写两次剩余追加:
getItemAt(one, oneIndex, &oneItem);
getItemAt(other, otherIndex, &otherItem);
while (oneIndex < oneCount && otherIndex < otherCount) {
cmpres = comparePolyItem(oneItem, otherItem);
if (cmpres > 0) {
appendPolyItem(res, oneItem);
getItemAt(one, ++oneIndex, &oneItem);
} else if (cmpres < 0) {
appendPolyItem(res, otherItem);
getItemAt(other, ++otherIndex, &otherItem);
} else {
xishu = oneItem.coefficient + otherItem.coefficient;
if (fabs(xishu) > 1e-6) {
resItem.coefficient = xishu;
resItem.power = oneItem.power;
appendPolyItem(res, resItem);
}
getItemAt(one, ++oneIndex, &oneItem);
getItemAt(other, ++otherIndex, &otherItem);
}
}
while (oneIndex < oneCount) {
appendPolyItem(res, oneItem);
getItemAt(one, ++oneIndex, &oneItem);
}
while (otherIndex < otherCount) {
appendPolyItem(res, otherItem);
getItemAt(other, ++otherIndex, &otherItem);
}
*result = res;
}