数据结构作业:一元多项式
问题描述(问题描述、问题分析、输入、输出样例的简单叙述)
①问题描述
设有一元多项式A(x)和B(x),现要求其相加结果C(x)=A(x)+B(x),其运算规则为:将两个多项式中指数相同的项对应系数相加,若和不为零,则构成C(x)中的一项; A(x)和B(x)中所有指数不相同的项均复抄到C(x)中。
②问题分析:
需求:实现两个一元多项式的加法运算。
实现功能:
通过键盘接收输入的整数(浮点数);
以系数和指数对应的形式,储存到计算机内存中;
实现一元多项式的加法运算;
通过屏幕输出一元多项式加法运算后的结果;
③输入输出样例
输入:分两次输入多项式,每次输入多项式的项数以及循环输入每一项的指数和系数。
输出:一行输出两个多项式相加的结果。
Eg:输入:
3
1 2
3 4
5 6
(代表多项式A:2X^1+4X^3+6X^5)
2
3 4
5 6
(代表多项式B:4X^3+6X^5)
输出:
2X^1+8X^3+12X^5
(代表最终结果多项式C:2X^1+8X^3+12X^5)
设计思路(设计思路、数据结构(所有变量说明)、算法描述(伪码的简单叙述))
①设计思路:
打算采用书中的链式存储来储存多项式的各项系数和指数。
使用的数据结构也和书上的一致,包含该项的系数,指数以及指向下一项的指针。
采用的算法和书上较为不同,书上没有新创建一个多项式,我选择新创建一个多项式C来进行求解。
②数据结构:
typedef struct NODE
{
int exp; //指数
float coef; //系数
struct NODE* next;
}Node,*Link;
③算法描述:
用带有头结点的线性链表表示多项式A(x),B(x),设指针hA,hB,hC分别为指向多项式链表A(x),B(x)的头指针,指针p,q的初始位置分别指向A(x),B(x)中第一项,则求A(x)+B(x)的运算过程为:比较p,q所指结点中的指数项,若EXP(p)<EXP(q),则把p节点存储的系数和指数传给C(x)新创建的一个节点,p指向下一个节点,q不动;若EXP(p)>EXP(q),则把q节点存储的的系数和指数传给C(x)新创建的一个节点,q指向下一个节点,p不动;若EXP(p)=EXP(q),则将两个结点中的系数相加,当和不为零时把这个和以及系数传给C(x)新创建的一个节点。如果有一个多项式的所有项都已经处理过,只需要把没处理完的多项式剩下的项全部加到C(x)即可。
测试用例和结果说明
图片上传不了就不在这边写了,大家随便测测就好,应该都是没问题的。(从小到大输入多项式哦
)
设计及测试过程
过程:
①在开始设计时,考虑到功能分块,所以写了以下几个函数:
Link Create(int num) //用于创建多项式
Link AddPoly(Link heada, Link headb) //多项式运算
void printpoly(Link head) //打印(输出)
②一开始没有考虑到多项式可能有存在小数的可能,所以使用了int型存储系数。后来,改为了float型。从我的数据结构中的float coef;即可看出。
③经过测试,发现改成float型后,输出会变得很不直观,小数点位数过长,所以在printploy函数的中把原来的printf修改为这样:printf("%.1fX^%d", p->coef, p->exp),就避免了输出太丑。
④在写算法的时候没有考虑到可能多项式系数经过运算可能为负数,所以在测试时,原先如果有某一项相加结果是负数,则会出现“+-”这样的情况。所以在程序中加入判断:
if(p->coef>0) //如果系数是负数则加个括号
printf("%.1fX^%d", p->coef, p->exp);
else
printf("(%.1f)X^%d", p->coef, p->exp);解决了问题。
评价和改进(算法的有点和缺陷、你的想法)
①可以添加自动排序功能,这样输入的时候可以不用管顺序,然后程序自动找到链表合适的位置插入。
②可以不用新创建一个链表,直接对比两个多项式,进行插入、删除、合并等功能。这样可以占用更少的空间。如果是把最高次项的次数较小的多项式,加到最高次项的次数较大的多项式中,那么,如果最高次项的次数较小的多项式全部处理过了就可以直接停止处理,在时间上也有所改进。
③在输入的时候可以设计一个检查模块,如果输入的数据不符合要求,程序会进行提醒,并让用户重新输入直到符合要求为之。
④可以加入一个询问模块,问用户十分需要继续添加项数,这样用户无需在一开始的时候就确定需要输入多项式的项数。当然,这个问题不是很大。
⑤如果两个多项式相加正好所有项都抵消,应该让程序输出“0”,而不是像我的程序一样什么也不输出。
⑥由于加法和减法对于本程序区别不大,所以稍加改进即可让用户选择对两个多项式进行加法还是减法运算。
⑦还有一个缺陷,如果输入中一个多项式中有次数相同的项,算法应该自动将它们相加,而不是像我的程序一样,都一起输出出来,没有处理。
⑧在输出时,如果输出到X的一次项,应不要在加上“^1”,当然这个问题也不是很大。
附:源程序(自行编写或修改的程序,有注释)
//一元多项式相加
#include <stdio.h>
#include <stdlib.h>
typedef struct NODE
{
int exp; //指数
float coef; //系数
struct NODE* next;
}Node,*Link;
Link Create(int num) //建立一个多项式(利用尾插法)
{
printf("\n");
int tempexp = 0; //临时指数
float tempcoef = 0; //临时系数
Link head = (Link)malloc(sizeof(Node));
head->next = NULL;
Link rear = head;
rear->next = NULL;
//输入部分&链接链表结点
for (int i = 1; i <= num; i++)
{
printf("请输入第%d项的次数和系数:", i);
scanf_s("%d %f", &tempexp, &tempcoef); //输入
Link temp = (Link)malloc(sizeof(Node));
temp->exp = tempexp;
temp->coef = tempcoef;
rear->next = temp;
rear = temp;
}
rear->next = NULL;
return head; //返回头结点
}
void printpoly(Link head) //打印多项式
{
Link p = head->next;
while (p != NULL)
{
if(p->coef>0) //如果系数是负数则加个括号
printf("%.1fX^%d", p->coef, p->exp);
else
printf("(%.1f)X^%d", p->coef, p->exp);
if (p->next != NULL)
printf("+"); //加号的打印
p = p->next;
}
}
Link AddPoly(Link heada, Link headb) //进行多项式相加减
{
Link headc = (Link)malloc(sizeof(Node));
headc->next = NULL;
Link rear = headc;
Link pa = heada->next;
Link pb = headb->next;
Link pc = headc->next;
while (pa != NULL || pb != NULL) //如果都为空就结束
{
Link temp = (Link)malloc(sizeof(Node));
temp->next = NULL;
if (pa != NULL && pb != NULL) //如果都不为空就可以找到合适的项加加减减
{
if ((pa->exp) < (pb->exp) ) //b的这一项指数大
{
temp->exp = pa->exp;
temp->coef = pa->coef;
rear->next = temp;
rear = temp;
pa = pa->next;
}
else if ((pa->exp) == (pb->exp)) //指数相同
{
if (pa->coef + pb->coef == 0) //系数如果加起来等于0什么也不做
{
pa = pa->next;
pb = pb->next;
}
else //系数加起来不为零
{
temp->exp = pa->exp;
temp->coef = pa->coef + pb->coef;
rear->next = temp;
rear = temp;
pa = pa->next;
pb = pb->next;
}
}
else if ((pa->exp) > (pb->exp) ) //a的这一项指数大
{
temp->exp = pb->exp;
temp->coef = pb->coef;
rear->next = temp;
rear = temp;
pb = pb->next;
}
}
else if (pa != NULL && pb == NULL)//b多项式所有项处理完了,a还没处理完
{
temp->exp = pa->exp;
temp->coef = pa->coef;
rear->next = temp;
rear = temp;
pa = pa->next;
}
else if (pa == NULL && pb != NULL)//a多项式所有项处理完了,b还没处理完
{
temp->exp = pb->exp;
temp->coef = pb->coef;
rear->next = temp;
rear = temp;
pb = pb->next;
}
}
return headc;
}
int main()
{
int n1 = 0, n2 = 0;
Link hc = NULL;
//创立多项式A
printf("\n构建多项式A\n");
printf("请输入多项式的项数:");
scanf_s("%d", &n1);
Link ha = Create(n1);
printf("多项式A:");
printpoly(ha);
printf("\n");
//创立多项式B
printf("\n构建多项式B\n");
printf("请输入多项式的项数:");
scanf_s("%d", &n2);
Link hb = Create(n2);
printf("多项式B:");
printpoly(hb);
printf("\n");
//计算出多项式C
hc=AddPoly(ha, hb);
printf("\nRESULT:\n多项式C:");
printpoly(hc);
return 0;
}