代码详见
目录
一、实习任务........................................................................................... - 1 -
1.问题描述:.................................................................................... - 1 -
2.小组分工........................................................................................ - 1 -
二、实习过程........................................................................................... - 1 -
1.程序思想..................................................................................... - 1 -
三、代码实现........................................................................................... - 4 -
原始版本........................................................................................... - 4 -
优化版本:..................................................................................... - 12 -
四、程序运行结果与分析..................................................................... - 15 -
五、用户使用说明书和参考资料......................................................... - 16 -
1.用户说明书.................................................................................. - 16 -
2.参考资料...................................................................................... - 16 -
实验总结................................................................................................. - 17 -
一元多项式计算课程设计任务书
一、实习任务
- 问题描述:
能够按照指数降序排列建立并输出多项式;能够完成两个多项式的相加、相减,并将结果输入。
①根据问题描述,设计系统函数。
②完成各函数的定义。
- 小组分工
张宇:完成代码以及查阅资料细节优化,完成报告。
鲁虹宇:完成部分代码以及构造程序框图,完成报告。
籍海洋:完成部分代码以及测试分析程序,完成报告。
二、实习过程
1.程序思想
(一)数据结构的描述
(1)一元多项式求和实质上是合并同类项的过程,其运算规则为:
①若两项的指数相等,则系数相加;
②若两项的指数不等,则将两项加在结果中。
一个较好的存储方法是只存非零元素,但是需要在存储非零元素系数的同时存储相应的指数。这样,一个一元多项式的每一个非零项可由系数和指数唯一表示。
本程序是利用单链表来表示一元多项式然后实现各项指数和系数的输入,进行多项式建立,并以多项式的形式输出,实现多项式的相加和相减这两种运算。由于两个一元多项式相加后,会改变多项式的系数和指数,因此采用顺序表不合适。 采用单链表存储,则每一个非零项对应单链表中的一个结点,且单链表应按指数递减有序排列。
一元多项式定义系数和指数结构如下:
coef域--存放结点的系数值 (即存放非零项的系数)
expn域--存放结点的指数值 (即存放非零项的指数)
next域--存放结点的直接后继的地址(位置)的指针域(链域)
定义多项式的结构为线性链表的存储结构,每个结点包含三个元素:系数coef,指数expn和指向下一个结点的指针*next。通过指针,我们就可以把多个单项式连接起来,形式一个多项式(单项式也是多项式)。
(2)建立多项式:尾插法建立一元多项式的链表,通过键盘输入多项式的系数和指数,以输入系数0为结束标志,并约定建立一元多项式链表时,总是按指数从小到大的顺序排列。
(3)输出多项式:从单链表的第一项开始逐项读出系数和指数,按多项式的形式输出。
(4)多项式相加:设p1和p2分别表示两个多项式。p1,p2,q分别表示指向单链表的当前项比较指数大小。如下:
①若p1->exp<p2->exp,则结点p1应是和多项式中的一项,将p1复制到q,并使p1后移。
②若p1->exp = p2->exp,则将两个结点中的系数相加,当和不为0时,p1的系数域加上p2的系数域作为和多项式的系数域;若和为0,则和多项式中没有这一项,p1,p2后移。
③若p1->exp > p2->exp,则将结点p2复制到q中,p2后移。
(5)多项式减法:将减数多项式的所有系数先变为相反数,然后调用多项式相加的函数进行运算。
图1程序框图
图2多项式减法流程图 图3多项式加法流程图
三、代码实现
原始版本
#include <stdio.h>
#include <stdlib.h>
struct Polynomial
{
int coef;
int exp;
struct Polynomial *next;
};
struct Polynomial *create();//建立多项式
struct Polynomial *insert(struct Polynomial *head,struct Polynomial *p);
void add(struct Polynomial *p1,struct Polynomial *p2);//多项式相加运算
void sub(struct Polynomial *p1,struct Polynomial *p2);//多项式相减运算
void print(struct Polynomial *p);//将多项式打印到屏幕
int main()
{
struct Polynomial *p1,*p2;
printf("请输入多项式A中x的系数及指数(输入0 0表示输入结束):\n");
p1=create();
printf("\n");
printf("A(x)=");
print(p1);
printf("请输入多项式B中x的系数及指数(输入0 0表示输入结束):\n");
p2=create();
printf("\n");
printf("B(x)=");
print(p2);
printf("\n\n");
printf("A(x)+B(x)=");
add(p1,p2);
printf("\n\n");
printf("A(x)-B(x)=");
sub(p1,p2);
printf("\n\n");
return 0;
}
struct Polynomial *create()
{
struct Polynomial *p,*q,*head;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
scanf("%d%d",&p->coef,&p->exp);
head=NULL;
while(p->coef!=0||p->exp!=0)
{
if(p->coef)
head=insert(head,p);
scanf("%d%d",&p->coef,&p->exp);
}
return head;
}
struct Polynomial *insert(struct Polynomial *head,struct Polynomial *p)
{
struct Polynomial *q,*q1,*q2,*t;
q=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->coef=p->coef;
q->exp=p->exp;
q->next=NULL;
if(head==NULL)
{
head=q;
head->next=NULL;
return head;
}
q2=q1=head;
while(q1!=NULL)
{
while(q1->exp>p->exp)
{
q2=q1;
if(q1->next==NULL)
break;
q1=q1->next;
}
if(q1->exp==p->exp)
{
q1->coef=q1->coef+p->coef;
if(q1->coef==0)
{
if(q1==head)
{
head=head->next;
break;
}
else
{
q2->next=q1->next;
}
}
else
break;
}
else if(q1->exp>p->exp)
{ t=q1->next;
q1->next=q;
q->next=t;
break;
}
else
{
if(q2==head&&q2->exp<q->exp) //如果不加q2->exp>q->exp会出现二义性
{
q->next=head;
head=q;
break;
}
else
{
q2->next=q;
q->next=q1;
break;
}
}
}
return head;
};
void add(struct Polynomial *p1,struct Polynomial *p2)
{
struct Polynomial*p,*q,*head;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
head=q=p;//插入排序的预备工作
while(p1!=NULL||p2!=NULL)
{
if(p1==NULL)
{
while(p2!=NULL)
{
q=p; //p的前一节点
p->exp=p2->exp;
p->coef=p2->coef;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->next=p;
p2=p2->next;
}
}
else if(p2==NULL)
{
while(p1!=NULL)
{
q=p;
p->exp=p1->exp;
p->coef=p1->coef;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->next=p;
p1=p1->next;
}
}
else
{
if(p1->exp>p2->exp)
{
q=p;
p->exp=p1->exp;
p->coef=p1->coef;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->next=p;
p1=p1->next;
}
else if(p1->exp==p2->exp)
{
q=p;
p->exp=p1->exp;
p->coef=p1->coef+p2->coef;
if(p->coef!=0)
{
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->next=p;
p1=p1->next;
p2=p2->next;
}
else
{
p1=p1->next;
p2=p2->next;
}
}
else
{
q=p;
p->exp=p2->exp;
p->coef=p2->coef;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->next=p;
p2=p2->next;//前一个系数比后一个大,看下一个
}
}
}
q->next=NULL;
print(head);
};
void sub(struct Polynomial *p1,struct Polynomial *p2)
{
struct Polynomial*p,*q,*head;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
head=q=p;
while(p1!=NULL||p2!=NULL)
{
if(p1==NULL)
{
while(p2!=NULL)
{
q=p;
p->exp=p2->exp;
p->coef=-p2->coef;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->next=p;
p2=p2->next;
}
}
else if(p2==NULL)
{
while(p1!=NULL)
{
q=p;
p->exp=p1->exp;
p->coef=p1->coef;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->next=p;
p1=p1->next;
}
}
else
{
if(p1->exp>p2->exp)
{
q=p;
p->exp=p1->exp;
p->coef=p1->coef;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->next=p;
p1=p1->next;
}
else if(p1->exp==p2->exp)
{
q=p;
p->exp=p1->exp;
p->coef=p1->coef-p2->coef;
if(p->coef!=0)
{
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->next=p;
p1=p1->next;
p2=p2->next;
}
else
{
p1=p1->next;
p2=p2->next;
}
}
else
{
q=p;
p->exp=p2->exp;
p->coef=-p2->coef;
p=(struct Polynomial *)malloc(sizeof(struct Polynomial));
q->next=p;
p2=p2->next;
}
}
}
q->next=NULL;
print(head);
};
void print(struct Polynomial *p)//将多项式打印到屏幕
{
struct Polynomial *p1;
p1=p;
if(p==NULL)
{
printf("0\n");
return;
}
while(p1!=NULL)
{
if(p1==p) //头结点输出时的情况
{
if(p1->coef==1&&p1->exp==0)
printf("1");
else if(p1->coef==-1&&p1->exp==0)
printf("-1");
else if(p1->coef==-1)
printf("-");
else if (p1->coef!=1)
printf(" %d",p1->coef);
if(p1->exp==1)
printf("x");
else if(p1->exp)
printf("x^%d ",p1->exp);
}
else
{
if(p1->coef>0)
{
if(p1->coef!=1)
printf("+ %d",p1->coef);
else if(p1->exp==0)
printf("+ 1");
else printf("+");
if(p1->exp==1)
printf("x ");
else if(p1->exp)
printf("x^%d ",p1->exp);
}
else
{
if(p1->coef==-1&&p1->exp==0)
printf("- 1");
else if(p1->coef==-1)
printf("- ");
else
printf("- %d",-p1->coef);
if(p1->exp==1)
printf("x ");
else if(p1->exp)
printf("x^%d ",p1->exp);
}
}
p1=p1->next;
}
printf("\n");
}
优化版本:
#include<cstdio>
#include<list>
using namespace std;
struct polynomial {
int coef;//系数
int exp;//指数
bool operator < (const struct polynomial b)const {
return exp>b.exp;
}
};
void comp( list<struct polynomial> &l) {//计算表达式
list<struct polynomial> ans;
l.sort();
list<struct polynomial>::iterator iter=l.begin();
while(l.size()) {
struct polynomial temp;
temp.exp=iter->exp;
temp.coef=iter->coef;
iter=l.erase(iter);
while(iter->exp==temp.exp&&l.size()) {
temp.coef+=iter->coef;
iter=l.erase(iter);
}
if(temp.coef)
ans.insert(ans.end(),temp);
}
for(iter=ans.begin(); iter!=ans.end(); ++iter) {
if(iter==ans.begin()) {
if(iter->coef==1&&iter->exp==0)
printf("1");
else if(iter->coef==-1&&iter->exp==0)
printf("-1");
else if(iter->coef==-1)
printf("-");
else if (iter->coef!=1)
printf(" %d",iter->coef);
if(iter->exp==1)
printf("X");
else if(iter->exp)
printf("X^%d ",iter->exp);
} else {
if(iter->exp) {//X项输出形式系数指数讨论
if(iter->coef>1&&iter->exp!=1)
printf("+%dX^%d ",iter->coef,iter->exp);
else if(iter->coef<-1&&iter->exp!=1)
printf("%dX^%d ",iter->coef,iter->exp);
else if(iter->coef==1&&iter->exp!=1)
printf("+X^%d ",iter->exp);
else if(iter->coef==-1&&iter->exp!=1)
printf("-X^%d ",iter->exp);
else if(iter->coef==1&&iter->exp==1)
printf("+X ");
else if(iter->coef==-1&&iter->exp==1)
printf("-X ");
else if(iter->exp==1&&iter->coef<-1)
printf("%dX ",iter->coef);
else if(iter->exp==1&&iter->coef>1)
printf("+%dX ",iter->coef);
} else if(iter->coef>0)printf("+%d ",iter->coef);
else printf("%d ",iter->coef);
}
}
l=ans;
}
void scan(list<struct polynomial> &l) {//输入表达式
int coef, exp;
while(scanf("%d %d",&coef,&exp)) {
struct polynomial p;
if(!coef&&!exp)
break;
if(coef) {
p.coef=coef;
p.exp=exp;
l.insert(l.end(),p);
}
}
printf("表达式如下:\n");
comp(l);
printf("\n");
}
void operate(list<struct polynomial> &l) {//操作选择
int choice;
printf("输入操作选择:\n");
printf("1.加法 2.减法\n");
while(1) {
scanf("%d",&choice);
if(choice==1||choice==2)
break;
printf("输入错误,重新输入\n");
}
if(choice==2)
for(list<struct polynomial>::iterator iter=l.begin(); iter!=l.end(); ++iter)
iter->coef*=-1;
};
int main() {
list<struct polynomial> la,lb;
printf("请输入多项式A中x的系数及指数(输入0 0表示输入结束):\n");
scan(la);
printf("请输入多项式B中x的系数及指数(输入0 0表示输入结束):\n");
scan(lb);
operate(lb);
la.merge(lb);
printf("运算结果如下:\n");
comp(la);
return 0;
}
四、程序运行结果与分析
代码(一)运行截图
代码(二)减法运算运行截图
代码(二)加法运算运行截图
五、用户使用说明书和参考资料
- 用户说明书
输入表达式按照:系数 指数 的格式输入,输入的结束以0 0 作为结束标志,两个表达式输入完毕后选择加减法进行计算即可。
算法的时间复杂度:第一种时间复杂度由于存在插入排序的限制,导致程序总体的时间复杂度为O(n^2)。
第二种优化程序由于使用了双指针链表实现了归并排序,并且加减法全部转化为加法,使得总体时间复杂度为O(n logn)。
- 参考资料
[1] C程序设计 谭浩强编著 清华大学出版社 2010.6
[2] 数据结构(C语言版) 严蔚敏 吴伟民 清华大学出版社 2011.11
[3] 面向对象程序设计与Visual C++6.0教程 陈天华 清华大学出版社 2006.1
[4] 操作系统教程 孙钟秀 高等教育出版社2005.7
标签:一元,p1,struct,课设,coef,多项式,iter,exp,Polynomial From: https://blog.51cto.com/u_16171407/6561296