资源描述
二○一五~二○一六 学年第 二 学期
信息科学与工程学院
软件综合设计报告书
课程名称: C语言课程设计
班 级:
学 号:
姓 名:
指导教师:
二○一六 年 六 月
一、需求分析
用单链表实现任意两个一元多项式的加、减法运算
任务:编程实现以下功能:
① 分别输入一元多项式pn (x)和Q n (x)。
从键盘输入一元对项式中各项的系数和指数,并用单链表加以表示。
② 分别对一元多项式pn (x)和Q n (x)进行升幂排序。
将一元多项式中各子项按照指数从小到大的顺序排序。
③ 分别输出一元多项式pn (x)和Q n (x)。
将用单链表表示的一元多项式输出,即打印多项式的系数和指数。
④ 任意输入一个实数x0,分别求出一元多项式pn (x0)和Q n (x0)的值。
⑤ 已知有两个一元多项式分别为Pn (x)和Qn (x),求出两个多项式的和
R n (x)和差T n (x),分别用单链表表示R n (x)和T n (x),并将二者输出,
(R n (x)=P n (x)+Q n (x),T n (x)=P n (x)-Q n (x))
⑥ 保存多项式,即分别将一元多项式pn (x)和Q n (x)各项的系数和指数保存到外部磁盘文件。
⑦ 由程序从所存文件中读出多项式的系数和指数,重新构建一元多项式 Pn (x) 和Q n (x),并可对其再次进行运算操作。
用户操作流程:
(1) 进入菜单界面;
(2) 根据提示输入对应功能数字,调用功能;
(3) 根据提示输入参数;
(4) 选择功能输出结果;
(5) 退出。
二、 概要设计
1、 系统总体设计框架:
主程序
功能选择函数
输入数据函数
升幂函数
赋值函数
求和求差函数
输出结果函数
2、 系统功能模块
(1) 功能选择函数:通过输入对应功能的数字,调用对应的函数进行多项式的运算。
(2) 输入数据函数:采用尾插法建立单链表并输入保存两个多项式的各项指数和系数。
(3) 升幂函数:通过冒泡排序法对两个多项式进行升幂排序。
(4) 求和求差函数:定义空链用来存储结果,将两个多项式相加减分别得到Rn(x)和Tn(x)。
(5) 输出函数:输出当前保存的多项式。
三、详细设计
创建一元多项式链表,链表中的每一个结点存放多项式的一个系数非零项,它包含三个域,分别存放该项的系数、指数以及指向下一个多项式项结点的指针。对每一项的系数和指数进行相应的操作完成计算
1. 定义结构体struct
使用typedef和struct定义的新类型名称,声明和初始化结构体变量;创建并根据自己的意愿初始化结构数组。
2. 建立单链表并输入保存一元多项式各项的系数和指数。单链表有两个域,data域和next域,一个是存放数据,一个是存放指针而且指向它的后继。将表的最后一个结点的next置NULL,以示表的结束。由于Pn(x)和Qn(x)的输入方式一样,所以在这里就只讨论Pn(x)的输入。在输入系数和指数的时候,在最后输入0以示输入结束。
开始
一次输入Pn(x)各项的系数和指数
将输入的数据作为多项式保存
调用函数
显示保存的一元多项式
结束
3. 建立功能选择函数
通过switch来判断外界输入的数字,调用对应的函数
开始
输入要调用函数的数字
判断输入的数字是否合法
通过switch判断返回对应的功能函数
调用该函数
结束
4. 多项式相加减:
多项式相加的运算规则是:两个多项式中所有指数相同的项的对应系数相加,若和不为零,则构成“和多项式”中的一项;所有指数不相同的的项均复抄到“和多项式”中。以单链表作为存储结构,并且“和多项式”中的节点无需另外生成,则可看做是将多项式Q加到多项式P中,由此得到下列运算规则:(设p、q分别是多项式Pn(x)和Qn(x)的一项,比较结点的指数项);
若p->exp<q->exp,则结点p所指的结点应是“和多项式”中的一项,令指针p后移。
若p->exp>q->exp,则结点q所指的结点应是“和多项式”中的一项,将结点q插入在结点p之前,且令指针q在原来的链表上后移。
若p->exp=q->exp,则将两个结点的系数相加,当和不为零是修改结点p的系数,释放q结点;若和为零,则“和多项式”中无此项,从P中p结点,同时释放p和q结点。 多项式相减运算规则同加法。
求和函数程序流程图:
开始
定义用来存储结果的空链R
调用排序函数先对多项式进行升幂排序
判断链表P是否为空?
判断链表Q是否为空?
将P、Q同指数项的系数相加然后赋给R
直接将多项式P的各项系数指数赋给R
直接将多项式Q的各项系数指数赋给R
输出结果R
结束
是
是
否
否
求差函数程序流程图:
开始
调用排序函数先对多项式进行升幂排序
定义用来存储结果的空链T
判断链表P是否为空?
判断链表Q是否为空?
将P、Q同指数项的系数相减然后赋给R
输出结果T
结束
直接将多项式P的各项系数指数赋给T
将多项式Q的系数变负后再赋给T
是
是
否
否
四、主要源程序代码
#include <stdio.h>
#include <math.h>
#include <algorithm>
typedef struct Ploynode
{
int coef;
int exp;
struct Ploynode *next;
}DXS;
int get()
{
int num;
printf("输入选择功能对应的数字: ");
scanf("%d", &num);
return num;
}
void fun1( DXS *PHEAD, DXS *QHEAD )
{
int e, c;//定义指数系数
printf("请输入P(x)中各项的系数和指数\n");
scanf("%d %d", &c, &e);
while( c != 0 || e != 0 ) /*若c=0,则代表多项式的输入结束*/
{
DXS *p = (DXS*) malloc(sizeof(DXS));/*申请新的结点*/
p->coef = c;
p->exp = e;
PHEAD->next = p;/*在当前表尾做插入*/
p->next = NULL; /*将表的最后一个结点的next置NULL,以示表结束*/
PHEAD = PHEAD->next;
scanf("%d %d", &c, &e);
}
printf("请输入Q(x)中各项的系数和指数\n");
scanf("%d %d", &c, &e);
while( c != 0 ||e != 0 ) /*若c=0,则代表多项式的输入结束*/
{
DXS *p = (DXS*) malloc(sizeof(DXS));/*申请新的结点*/
p->coef = c;
p->exp = e;
QHEAD->next = p; /*在当前表尾做插入*/
p->next = NULL; /*将表的最后一个结点的next置NULL,以示表结束*/
QHEAD = p;
scanf("%d %d", &c, &e);
}
printf("输入5显示结果\n");
}
void fun2( DXS *PHEAD, DXS *QHEAD )//升幂排序
{
DXS *p, *q;//链表的冒泡排序
p = PHEAD->next;
for( p; p != NULL; p = p->next )
{
for( q = p->next; q != NULL; q = q->next )
{
if( p->exp > q->exp )
{
int temp;
temp = p->coef;
p->coef = q->coef;
q->coef = temp;
temp = p->exp;
p->exp = q->exp;
q->exp = temp;
}
}
}
p = QHEAD->next;
for( p; p != NULL; p = p->next )
{
for( q = p->next; q != NULL; q = q->next )
{
if( p->exp > q->exp )
{
int temp;
temp = p->coef;
p->coef = q->coef;
q->coef = temp;
temp = p->exp;
p->exp = q->exp;
q->exp = temp;
}
}
}
printf("输入5显示结果。\n");
}
void fun5( DXS *PHEAD, DXS *QHEAD )
{
printf("当前保存的P(x),Q(x)序列如下:\n");
printf("P(x)=");
while( PHEAD->next != NULL )
{
PHEAD = PHEAD->next;
printf("%dx^%d", PHEAD->coef, PHEAD->exp);
if( PHEAD->next != NULL )
{
printf(" + ");
}
}
printf("\n");
printf("Q(x)=");
while( QHEAD->next != NULL )
{
QHEAD = QHEAD->next;
printf("%dx^%d", QHEAD->coef, QHEAD->exp);
if( QHEAD->next != NULL )
{
printf(" + ");
}
}
printf("\n\n");
}
void fun4( DXS *PHEAD, DXS *QHEAD )
{
int x0; double sum;
printf("输入x的值: ");
scanf("%d", &x0);
sum = 0;
while( PHEAD->next != NULL)
{
PHEAD = PHEAD->next;
sum += PHEAD->coef * pow( x0, PHEAD->exp );
}
printf("P(x) = %.0lf\n", sum);
sum = 0;
while( QHEAD->next != NULL )
{
QHEAD = QHEAD->next;
sum += QHEAD->coef * pow( x0, QHEAD->exp );
}
printf("Q(x0) = %.0lf\n\n", sum);
}
void fun3( DXS *PHEAD, DXS *QHEAD )//求两个多项式的和差
{
fun2( PHEAD, QHEAD );//先进行升幂排序
DXS *RHEAD, *THEAD;
RHEAD = (DXS*) malloc(sizeof(DXS));
THEAD = (DXS*) malloc(sizeof(DXS));
RHEAD->next = NULL;
THEAD->next = NULL;
DXS *p = PHEAD, *q = QHEAD; //多项式相加
DXS *r = RHEAD;
p = p->next;
q = q->next;
while( p != NULL && q != NULL )//当两个序列都有数值时
{
DXS *t = (DXS*) malloc(sizeof(DXS));
if ( p->exp == q->exp )//指数相同的情况
{
t->coef = p->coef + q->coef;
t->exp = p->exp;
p = p->next;
q = q->next;
}
else if( p->exp < q->exp )//P的指数小于Q的指数
{
t->coef = p->coef;
t->exp = p->exp;
p = p->next;
}
else if( p->exp > q->exp )//P的指数大于Q的指数
{
t->coef = q->coef;
t->exp = q->exp;
q = q->next;
}
r->next = t;
r = r->next;
r->next = NULL;
}
while ( p != NULL )//当只有一个序列有数值时
{
DXS *t = (DXS*) malloc(sizeof(DXS));
t->coef = p->coef;
t->exp = p->exp;
r->next = t;
r = r->next;
r->next = NULL;
p = p->next;
}
while ( q != NULL )
{
DXS *t = (DXS*) malloc(sizeof(DXS));
t->coef = q->coef;
t->exp = q->exp;
r->next = t;
r = r->next;
r->next = NULL;
q = q->next;
}
r = RHEAD;
printf("R(x) = ");
while( r->next != NULL )
{
r = r->next;
if (r->coef>=0)
{
if(r!=RHEAD->next)
printf(" + ");
printf("%dx^%d",r->coef,r->exp);
}
else
printf(" - %dx^%d",-1*r->coef,r->exp);
}
printf("\n\n");
p = PHEAD;
q = QHEAD;
DXS *T = THEAD; //多项式相减
p = p->next;
q = q->next;
while( p != NULL && q != NULL )
{
DXS *t = (DXS*) malloc(sizeof(DXS));
if ( p->exp == q->exp )
{
t->coef = p->coef - q->coef;
t->exp = p->exp;
p = p->next;
q = q->next;
}
else if( p->exp < q->exp )
{
t->coef = p->coef;
t->exp = p->exp;
p = p->next;
}
else if( p->exp > q->exp )
{
t->coef = -1 * q->coef;
t->exp = q->exp;
q = q->next;
}
T->next = t;
T = T->next;
T->next = NULL;
}
while ( p != NULL )
{
DXS *t = (DXS*) malloc(sizeof(DXS));
t->coef = p->coef;
t->exp = p->exp;
T->next = t;
T = T->next;
T->next = NULL;
p = p->next;
}
while ( q != NULL )
{
DXS *t = (DXS*) malloc(sizeof(DXS));
t->coef = -1 * q->coef;
t->exp = q->exp;
T->next = t;
T = T->next;
T->next = NULL;
q = q->next;
}
T = THEAD;//消除系数为0项
while ( T->next != NULL )
{
if( T->next->coef == 0 )
{
T->next = T->next->next;
}
T = T->next;
if( T == NULL )
break;
}
T = THEAD;
printf("T(x) = ");
while( T->next != NULL )
{
T = T->next;
if( T->coef >=0 )
{
if(T!=THEAD->next)
printf(" + ");
printf("%dx^%d",T->coef,T->exp);
}
else
printf(" - %dx^%d", -1 * T->coef, T->exp);
}
if (THEAD->next==NULL)
printf("0\n");
printf("\n");
}
void menu()
{
printf("-----------------------------------------------\n");
printf("1.分别输入Pn(x)和Qn(x)。\n");
printf("2.分别对Pn(x)和Qn(x)进行升幂排序。\n");
printf("3.分别求出Pn(x)和Qn(x)的和差。\n");
printf("4.任意输入一个实数x,分别求出一元多项式Pn(x)和Qn(x)的值。\n");
printf("5.分别输出上一步运行结果的Pn(x)和Qn(x)。\n");
printf("-----------------------------------------------\n");
printf("If you want to exit the system,please input 0.\n"); }
int main()
{
printf("Welcome to the menu~~\n");
menu();
int num;
num = get();
if ( num == 0 )
printf("\nExit the system,goodbye~~\n");
DXS *PHEAD, *QHEAD;
PHEAD = (DXS *)malloc(sizeof(DXS));
QHEAD = (DXS *)malloc(sizeof(DXS));
PHEAD->next = NULL;
QHEAD->next = NULL;
while ( num )
{
switch ( num )
{
case 1:
fun1( PHEAD, QHEAD ); break;
case 2:
fun2( PHEAD, QHEAD ); break;
case 3:
fun3( PHEAD, QHEAD ); break;
case 4:
fun4( PHEAD, QHEAD ); break;
case 5:
fun5( PHEAD, QHEAD ); break;
default:
printf("输入错误,请重新输入\n\n");
}
num = get();
if ( num == 0 )
printf("\nExit the system,goodbye!\n");
}
return 0;
}
五、调试分析过程描述
1.进入菜单界面,调用功能1完成多项式的输入,再调用功能5显示结果。
2.调用功能2对多项式进行排序。
3.调用功能3计算Pn(x)、Qn(x)的和差Rn(x)和Tn(x)。
5. 调用功能4计算当x=2时,多项式的值。
6. 当Pn(x)和Qn(x)相减得到Tn(x)后,系数为0的项会直接去掉。
7.当输入其他数字比如0时,程序就会退出系统。
六、设计小结
通过这次课程设计实验,我学到了很多东西。多项式在计算机里的存储样式并不像其在我们眼前那样直观,在计算机里,只需要多项式每一项的系数和指数就可以表示多项式了。运行程序后,呈现在我们眼前的是简洁明了的界面,而这些画面都是由程序里的printf来输出的,从功能界面是看不到程序内部结构的。当我输入不同的数字,内部的程序就会调用对应的函数得到想要的结果。这次程序设计中,我只完成了前5个要求。要求6和7设计的C语言内容我们还并未学过,虽然看了书,对fwrite函数和fread函数有了一定的了解,但很遗憾的是由于时间有限还是没能做出来。在设计的过程中难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,比如说结构体。通过这次课程设计之后,一定把以前所学过的知识重新温故。
展开阅读全文