想要记录自己编程思维的成长所以发到博客,欢迎并且感激大家指出缺点和错误!
一、【实验构思(Conceive)】
本次实验要求是用C或C++语言设计并实现一个一元稀疏多项式的简单计算器,要求是要有如下功能
1、输入并建立多项式
2、输出多项式,序列按指数降序排列
3、多项式A(x)和B(x)相加,并建立多项式A(x)+B(x)
4、多项式A(x)和B(x)相减,并建立多项式A(x)-B(x)
5、给定 x 的值,计算多项式
6、多项式A(x)和B(x)相乘,建立多项式A(x)B(x) ( 选做,作为难度B的 操作)
二、【实验设计(Design)】
-
考虑一元多项式的数据结构(数据对象,数据关系,其上操作)如何表示与实现;
-
具体建立有头结点的一元多项式的结构实现用结构体实现,一个节点数据有两个,一个是double,一个是int,分别用来存储每一项的系数和指数,还有一个指针域的struct类型的指针next,指向下一个结点。
-
用createPolyn(Polyn, int)函数创建名为head的多项式,提示用户输入第一个多项式要输入几项,createPolyn()函数内调用insert()函数,插入输入的每一项,插入是即排序(序列按指数降序排列)
-
用printPolyn()函数实现打印,要分为多种情况:
1.系数大于0用‘+’连接,本身无符号,小于0的负数本身有符号‘-’,就不理会。
2.若系数为0,此项就为0
3.若系数不为0,
1)为1,不打印系数1:
指数为0,打印‘1’
指数为1,打印‘X’
2)为-1,不打印1,只打印‘-’
指数为0,打印‘-1’
指数为1,打印’-X’
3)其他数,打印‘系数X^指数 -
addPolyn()函数实现:用新链表hc来存结果,计算过程中,用cmp()函数比较两当前指针所指节点的指数大小,经过比较,决定是直接插入hc还是相加两节点系数值再判断是否为0后插入hc或者释放系数为0的节点,经过一次节点计算后,据情况指针后移。
-
subPolyb()函数即将第=减数多项式取反再调用addPolyn(),将取反后的多项式与原被减数多项式相加。
-
multiPolyn()函数实现:用新链表hc来存结果,计算过程中,第一个多项式的每一项都要去乘第二个多项式的所有项然后相加之和,有嵌套for循环实现,内层循环每次建立新hc节点来存储并插入结果。
-
derivation()求导函数实现,即将每一个指数不为0的项的系数指数重新赋值,系数=系数*指数 ,指数=指数- 1。
-
valueCount()函数的实现,输入X的值,再将其代入计算即得结果,同时计算输入的多项式a和b。
-
destroyPolyn()函数,每次结束一次操作就将多项式进行销毁,具体操作为节点存在即释放,销毁成功即返回OK,多项式不存在销毁失败,即返回FAILED。
-
cmp()函数用来比较两多项式中指针当前所指项系数大小.
三、【实现(Implement)】
抽象数据类型实现代码:
typedef struct lNode{
double coef;//多项式的系数
int expn;//多项式的指数
struct lNode *next;//指向下一个多项式的结点的指针
}*Polyn,Polynomial;
操作函数声明:
//操作函数声明
void Insert(Polyn, Polyn); //
Polyn createPolyn(Polyn,int);//建立一个头结点为head、项数为m的一元多项式
status destroyPolyn(Polyn);//销毁一元稀疏多项式链表,程序结束前应调用此函数释放多项式链表内存
void printPolyn(Polyn);//注意打印分类
//实现多项式的加减乘,求导
Polyn addPolyn(Polyn, Polyn);
Polyn subPolyn(Polyn, Polyn);
Polyn multiPolyn(Polyn, Polyn);
Polyn derivation(Polyn);
int cmp(Polyn, Polyn);
int valueCount(Polyn, int);
函数定义
status destroyPolyn(Polyn HEAD){//销毁存在的多项式链表
Polyn h, q = HEAD;
if(h == NULL)
return FAILED;
while(q){//循环销毁链表
Polyn p = q;
q = q -> next;
free(p);
}
return OK;
}
Polyn createPolyn(Polyn HEAD, int n){//输入m项的系数和指数,建立表示一元多项式的有序链表
int i;
Polyn p;
p = HEAD = (Polyn)malloc(sizeof(Polyn));
HEAD->next = NULL;
for(i = 0; i < n; i++)
{
p = (Polyn)malloc(sizeof(Polyn));//建立新结点以接收数据
printf("请输入第%d项的系数与指数(输入一个数就按回车):\n", i+1);
scanf("%lf %d", &p->coef, &p->expn);//注意double类型接收说明是%lf
Insert(p, HEAD); //调用Insert函数插入结点 将p节点插入链表HEAD中
}
return HEAD;
}
void Insert(Polyn p,Polyn HEAD){ //插入一项 就立刻排序 (插入算法)
if(p->coef == 0)
free(p);//系数为0的话没意义释放结点
else
{
Polyn q1,q2;
q1 = HEAD;//q1指向头结点
q2 = HEAD -> next;//q2指向第一个结点(也就是多项式第一项)
while(q2 && p->expn < q2->expn)//条件是q2指向的那一项 存在 且p输入的这一项的指数小于q2指向的那一项的指数(指数按从大到小排序)
{//查找插入位置
q1=q2;//q1指向下一项
q2=q2->next;//q2指向下一项
}
if(q2 && p->expn == q2->expn)
{//将指数相同相合并
q2->coef += p->coef;
free(p);//释放被合并的一项
if(!q2->coef) //若合并后原来的节点系数为O了也就释放原来的结点
{
q1->next = q2->next;
free(q2);
}
}
else
{//指数为新时将结点插入q1与q2之间
p->next = q2;
q1->next = p;
}
}
}
void printPolyn(Polyn HEAD){//在过程中使用,或者主函数调用
Polyn q;
q = HEAD->next;
int count;
count = 0;
if(!q){
printf("0\n");
return;
}
while(q){
if(q->coef > 0 && count != 0)//系数大于0的情况
printf("+");