长整数四则运算+阶乘+乘方数据结构课程设计保证原创性.docx
《长整数四则运算+阶乘+乘方数据结构课程设计保证原创性.docx》由会员分享,可在线阅读,更多相关《长整数四则运算+阶乘+乘方数据结构课程设计保证原创性.docx(32页珍藏版)》请在冰豆网上搜索。
![长整数四则运算+阶乘+乘方数据结构课程设计保证原创性.docx](https://file1.bdocx.com/fileroot1/2022-12/30/def6b26a-b335-40fd-884c-0c1637bf0b29/def6b26a-b335-40fd-884c-0c1637bf0b291.gif)
长整数四则运算+阶乘+乘方数据结构课程设计保证原创性
数据结构课程设计报告
题目:
长整数四则运算
学院计算机学院
专业计算机科学与技术
年级班别2010级四班
学号3110006015
学生姓名张法光
指导教师张巍
成绩____________________
2012年6月
一、需求分析
1、设计一个实现任意长的整数进行四则运算的程序。
2、利用双向循环链表实现长整数的存储,每个结点含一个整型变量。
3、输入和输出形式是按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开,长整数位数没有上限,以分号结束长整型数据的输入。
4、实现长整数四则运算、阶乘和乘方运算。
4、测试数据:
(以加法为例)
(1)、0;0;+;应输出“0”。
(2)、-2345,6789;-7654,3211;+;应输出“-1,0000,0000”。
(3)、-9999,9999;1,0000,0000,0000;+;应输出“9999,0000,0001”.
(4)、1,0001,0001;-1,0001,0001;+;应输出“0”.
(5)、1,0001,0001;-1,0001,0000;+;应输出“1”。
(6)、-9999,9999,9999;-9999,9999,9999;+;应输出“-1,9999,9999,9998”.
(7)1,0000,9999,9999;1;+;应输出“1,0001,0000,0000”.
2、概要设计
为了实现上述功能,采取双向循环链表表示长整数,每个结点含一个整型变量,且仅绝对值不超过9999的整数,整个链表用十进制数表示。
利用头结点数据域的符号表示长整数的符号,相加过程不破坏两个操作数链表,对长整数位数不作上限。
为此需要两个结构数据类型:
双向循环链表和长整数,两个类型采用相同的结构,只是双向循环链表用来存储数据,长整型用表示数据的运算。
1、双向循环链表的数据结构及操作定义如下:
typedefintStatus;
typedefintElemType;
typedefstructDuLNode//双向循环链表结点
{
ElemTypedata;
structDuLNode*prior;
structDuLNode*next;
}DuLNode,*DuLinkList;
typedefstruct//双向循环链表
{
DuLinkListhead;//双向循环链表头结点,不存放数据
intlen;//双向循环链表中的结点个数,头结点不计
}LinkList;
基本操作:
StatusInitList(LinkList&L);
//构造一个空的线性链表
voidClearList(LinkList&L);
//将线性链表L重置为空表,并释放原链表的结点空间
StatusHeadInser(LinkList&L,ElemTypee);
//在线性链表的头结点后插入数据元素为e的新结点
StatusTailInser(LinkList&L,ElemTypee);
//在线性链表的头结点前插入数据元素为e的新结点
StatusHeadDelete(LinkList&L);
//删除头结点后的第一个结点
StatusListCopy(LinkList&L,LinkListL1);
//将L1复制给L,保持L1不变
2、长整数的数据类型和和操作定义为:
voidScanNum(LinkList&L);
//从键盘输入一个长整数,存至L;
voidPrintNum(LinkListL);
//在屏幕打印长整数L
voidNumChange(LinkList&L);
//将长整数L还原成一般格式
StatusNumLarger(LinkListL1,LinkListL2);
//比较正数L1与正数L2的大小,若L1大于或等于L2,返回TRUE,否则返回FALSE
voidNumPlus(LinkListL1,LinkListL2,LinkList&L3);
//将L1与L2相加,结果存至L3;即C=A+B;
voidNumMinus(LinkListL1,LinkListL2,LinkList&L3);
//计算L1减去L2的值,结果存至L3;即C=A-B;
voidNumMul(LinkListL1,LinkListL2,LinkList&L3);
//将L1与L2相乘,结果存至L3;即C=A*B;
StatusNumDiv(LinkListL1,LinkListL2,LinkList&L3,LinkList&L4);即C=A/B;
//计算L1除以L2,商存至L3,余数存至L4,若L2为零,返回ERROR,否则返回OK
Statusjiecheng(LinkListL1,LinkList&L2)即C=A!
;
//求L1的阶乘L2;若L1小于零,返还ERROR;否则返回OK;
Statuschengfang(LinkListL1,LinkListL2,LinkList&L3)即C=A^B;
//求L1的L2次方的结果,若L2小于零,返还ERROR;否则返回OK;
3、本程序包含四个模块:
1)主程序模块:
voidmain()//main.c
{
初始化;
do{
接受命令;
处理命令;
}while(“命令”=“结束”)
}
2)双向循环链表处理模块//LinkList.h;
3)
长整数运算模块//LongNum.h,jiecheng.h,chengfang.h;
4)界面模块//Interface.h
各模块之间的调用关系如下:
主程序模块
==========================================
长整数运算模块界面模块
======================
双向循环链表处理模块
=======================
3、详细设计
1、主要函数
主程序模块//main.c
双向循环链表处理模块//LinkList.h
长整数四则运算模块//LongNum.h
阶乘运算模块//jiecheng.h
乘方运算模块//chengfang.h
界面模块//Interface.h
charShowMenu()//界面菜单显示
charShowPlus()//加法运算显示
charShowMinus()//减法运算显示
charShowMul()//乘法运算显示
charShowDiv()//除法运算显示
charShowchengfang()//乘方运算显示
charShowjiecheng()//阶乘运算显示
2、
函数的主要调用关系图
Main
InitListClearListInterface
=============================
Show
ScanNumPrintNum
======================================================================
JiechengchengfangNumPlusNumMinusNumChangeNumMulNumLargerNumDiv
======================================================================
=========================================================
InitListClearListHeadInserTailInserHeadDeleteListCopy
4、调试分析及编程心得体会
刚开始使用C指针有偏颇,通过逐步调试修正错误。
函数调用时头文件也出现了一些问题,以及模块功能调用不完善。
通过逐步分析系统的结构层次和工程函数调用次序,解决了头文件和模块功能调用问题。
今后会多增加对工程函数的实践和分析。
五、用户手册
1、程序运行环境为DOS界面,执行文件为“长整数四则运算.exe”。
2、进入演示程序后即显示文本方式的用户界面
3、输入命令,执行相应的功能:
1––加法运算2––减法运算3––乘法运算4––除法运算
5––乘方运算6––阶乘运算7––退出系统
6、测试结果
(1)、加法运算
(2)、减法计算
(3)、乘法计算
(4)、除法计算
(5)、乘方计算
(6)、阶乘计算
七、源程序代码
1、main.c主程序
#include
#include
#include
#include
#include"Interface.h"
voidmain()
{//主函数
charselect,i;
i='1';
while
(1)
{
select=ShowMenu();
switch(select)
{
case'1':
while(i=='1')
{i=ShowPlus();}
i='1';
break;
case'2':
while(i=='1')
{i=ShowMinus();}
i='1';
break;
case'3':
while(i=='1')
{i=ShowMul();};
i='1';
break;
case'4':
while(i=='1')
{i=ShowDiv();};
i='1';
break;
case'5':
while(i=='1')
{i=Showchengfang();}
i='1';
break;
case'6':
while(i=='1')
{i=Showjiecheng();}
i='1';
break;
case'7':
printf("7\n\n感谢使用!
\n");
default:
break;
}
if(select=='7')break;
}
getch();
}
2、InterFace.h程序界面模块
#include"LinkList.h"
#include"LongNum.h"
#include"jiecheng.h"
#include"chengfang.h"
charShowMenu()
{//显示主菜单,返回选择
chari;
system("cls");
printf("\t\t------------------------------------------------------\n");
printf("\t\t1.加法\t\t2.减法\t\t3.乘法\t\t4.除法\n\n\t\t5.乘方\t\t6.阶乘\t\t7.退出\n");
printf("\t\t------------------------------------------------------\n\n输入选择:
");
i=getch();
fflush(stdin);
while(i>'7'||i<'1')
{//输入出错处理
i=getch();
fflush(stdin);
}
returni;
}
charShowPlus()
{//完成一次加法运算,返回下一步操作
chari=0;
LinkLista,b,c;
InitList(a);InitList(b);InitList(c);
system("cls");
printf("--------\n加法运算\n--------\n");
printf("输入数据,四位一组,用逗号隔开\n\n");
printf("A:
");ScanNum(a);
printf("B:
");ScanNum(b);
fflush(stdin);
NumPlus(a,b,c);
printf("\nA+B=");
PrintNum(c);putch('\n');
ClearList(a);ClearList(b);ClearList(c);
printf("\n\n\n\n\n\n请选择:
\n\n1.继续\t\t2.返回\n");
while(i!
='1'&&i!
='2')
{
i=getch();
}
fflush(stdin);
returni;
}
charShowMinus()
{//完成一次减法运算,返回下一步操作
chari=0;
LinkLista,b,c;
InitList(a);InitList(b);InitList(c);
system("cls");
printf("--------\n减法运算\n--------\n");
printf("输入数据,四位一组,用逗号隔开\n\n");
printf("A:
");ScanNum(a);
printf("B:
");ScanNum(b);
fflush(stdin);
NumMinus(a,b,c);
printf("\nA-B=");
PrintNum(c);putch('\n');
ClearList(a);ClearList(b);ClearList(c);
printf("\n\n\n\n\n\n请选择:
\n\n1.继续\t\t2.返回\n");
while(i!
='1'&&i!
='2')
{
i=getch();
}
fflush(stdin);
returni;
}
charShowMul()
{//完成一次乘法运算,返回下一步操作
chari=0;
LinkLista,b,c;
InitList(a);InitList(b);InitList(c);
system("cls");
printf("--------\n乘法运算\n--------\n");
printf("输入数据,四位一组,用逗号隔开\n\n");
printf("A:
");ScanNum(a);
printf("B:
");ScanNum(b);
fflush(stdin);
NumMul(a,b,c);
printf("\nA*B=");
PrintNum(c);putch('\n');
ClearList(a);ClearList(b);ClearList(c);
printf("\n\n\n\n\n\n请选择:
\n\n1.继续\t\t2.返回\n");
while(i!
='1'&&i!
='2')
{
i=getch();
}
fflush(stdin);
returni;
}
charShowDiv()
{//运行一次除法运算,并返回下一步选择
chari=0;
LinkLista,b,c,d;
InitList(a);InitList(b);InitList(c);InitList(d);
system("cls");
printf("--------\n除法运算\n--------\n");
printf("输入数据,四位一组,用逗号隔开\n\n");
printf("A:
");ScanNum(a);
printf("B:
");ScanNum(b);
fflush(stdin);
if(NumDiv(a,b,c,d))//判断是否出错
{
printf("\nA/B=");
PrintNum(c);
printf("\t余");
PrintNum(d);
putch('\n');
}
elseprintf("\n输入有误!
\n");
ClearList(a);ClearList(b);ClearList(c);ClearList(d);
printf("\n\n\n\n\n\n请选择:
\n\n1.继续\t\t2.返回\n");
while(i!
='1'&&i!
='2')
{
i=getch();
}
fflush(stdin);
returni;
}
charShowchengfang()//乘方
{
chari=0;
LinkLista,b,c;
InitList(a);InitList(b);InitList(c);
system("cls");
printf("--------\n乘方运算\n--------\n");
printf("输入数据,四位一组,用逗号隔开\n\n");
printf("A:
");ScanNum(a);
printf("n:
");ScanNum(b);
fflush(stdin);
if(chengfang(a,b,c))
{
printf("\nA^n=");
PrintNum(c);putch('\n');
ClearList(a);ClearList(b);ClearList(c);
}
elseprintf("\n输入有误!
\n");
printf("\n\n\n\n\n\n请选择:
\n\n1.继续\t\t2.返回\n");
while(i!
='1'&&i!
='2')
{
i=getch();
}
fflush(stdin);
returni;
}
charShowjiecheng()
{
chari=0;
LinkLista,b;
InitList(a);InitList(b);
system("cls");
printf("--------\n阶乘运算\n--------\n");
printf("输入数据,四位一组,用逗号隔开\n\n");
printf("A:
");ScanNum(a);
fflush(stdin);
jiecheng(a,b);
printf("\nA!
=");
PrintNum(b);putch('\n');
ClearList(a);ClearList(b);
printf("\n\n\n\n\n\n请选择:
\n\n1.继续\t\t2.返回\n");
while(i!
='1'&&i!
='2')
{
i=getch();
}
fflush(stdin);
returni;
}
3、LinkList.h双向循环链表处理模块
#include
#defineNULL0
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
typedefintStatus;
typedefintElemType;
typedefstructDuLNode//双向循环链表结点
{
ElemTypedata;
structDuLNode*prior;
structDuLNode*next;
}DuLNode,*DuLinkList;
typedefstruct//双向循环链表
{
DuLinkListhead;//双向循环链表头结点,不存放数据
intlen;//双向循环链表中的结点个数,头结点不计
}LinkList;
StatusInitList(LinkList&L);
//构造一个空的线性链表
voidClearList(LinkList&L);
//将线性链表L重置为空表,并释放原链表的结点空间
StatusHeadInser(LinkList&L,ElemTypee);
//在线性链表的头结点后插入数据元素为e的新结点
StatusTailInser(LinkList&L,ElemTypee);
//在线性链表的头结点前插入数据元素为e的新结点
StatusHeadDelete(LinkList&L);
//删除头结点后的第一个结点
StatusListCopy(LinkList&L,LinkListL1);
//将L1复制给L,保持L1不变
StatusInitList(LinkList&L)
{//构造一个空的线性链表
L.head=(DuLinkList)malloc(sizeof(DuLNode));
L.head->next=L.head;
L.head->prior=L.head;
L.len=0;
returnOK;
}
voidClearList(LinkList&L)
{//将线性链表L重置为空表,并释放原链表的结点空间
DuLinkListp;
while(L.head->next!
=L.head)
{
p=L.head->next;
p->next->prior=p->prior;
p->prior->next=p->next;
free(p);
}
L.len=0;
}
StatusHeadInser(LinkList&L,ElemTypee)
{//在线性链表的头结点后插入数据元素为e的新结点
DuLinkListp;
p=(DuLinkList)malloc(sizeof(DuLNode));
p->data=e;
p->next=L.head->next;
p->prior=L.head;
L.head->next->prior=p;
L.head->next=p;
++L.len;
returnOK;
}
StatusTailInser(LinkList&L,ElemTypee)
{//在线性链表的头结点前插入数据元素为e的新结点
DuLinkListp;
p=(DuLinkList)malloc(sizeof(DuLNode));
p->data=e;
p->prior=L.head->prior;
p->next=L.head;
L.head->prior->nex