课程名称: 《数据结构》课程设计课程设计题目: 任意长整数加法运算姓名: XXX专业: 计算机科技2班年级: 13级学号: E11314XXX指导老师:XXX2015年9月17目录1.课程设计的目的 (1)2.需求分析 (1)3任意长整数加法的设计 (2)3.1概要设计 (2)3.2详细设计 (3)3.3调试分析 (9)3.4用户手册 (10)3.5测试结果 (10)4总结 (11)5、程序清单:(见附录) (11)7、程序运行结果 (11)附录1 (13)1.课程设计的目的(1) 熟练使用 C 语言编写程序,解决实际问题;(2) 了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;(3) 初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;(4) 提高综合运用所学的理论知识和方法独立分析和解决问题的能力;2.需求分析(1)设计一个实现任意长的整数加法运算演示程序。
(2)利用双向链表实现长整数的存储,每个结点含一个整型变量。
(3)输入输出形式按中国对长整数的表示习惯,每四位一组,用逗号隔开。
3任意长整数加法的设计3.1概要设计(1)主界面设计图 1图2主界面,如图1所示,包含四个菜单项,输入数字选择对应菜单,进入子项。
其中选项2包含子菜单,如图2所示。
(2)存储结构本系统用结构体linlist存储数据,该结构体由数据data、下一节点指针next、上一节点指针prior组成。
data是short型变量,存放每个结点的数据。
本系统中data 一般不超过10000。
用结构体linlist构建链表,头结点的data域符号代表长整数的符号,绝对值表示链表结点数目。
(3)系统功能设计本系统主菜单包含四个选项,功能描述如下:菜单1:输入两个任意长的整数。
可按照标准四位一组中间用逗号隔开输入,也可直接输入,输入的数字保存在文件中,结束后自动返回主菜单。
菜单2:实现两个任意长整数的加法。
可直接输入两个数也可读入一个文件,获取两个加数,相加结果可保存在文件中,也可不保存,结束后返回菜单2。
菜单3:输入文件名称,查询文件中的数字。
文件中可能保存的是两个加数,也可能保存的是某次两个任意长整数相加的结果。
菜单4:退出系统。
3.2详细设计(1)系统子程序及功能设计本系统设置16个子程序,各程序的函数名及功能说明如下:void append(LinList &L,Elemtype d);//以L为头结点,将d加入到链表L void Delete(LinList &L);//删除结点Lvoid display(LinList L);//按照输出标准,输出任意长整数void add(LinList &L1,LinList L2);//将L1与L2相加short StrToPosiNum(char * s);//将s转化为一个小于32767的正整数void input(LinList &L);//输入一个很长的整数到Lvoid FREE(LinList &L1);//删除以L1为头结点的整个链表void save(LinList L1,LinList L2);//把L1,L2写到文件void load(LinList &L1,LinList &L2);//读文件到L1,L2void inputdata();//调用input函数,实现两个任意长整数的输入void welcome();//输出欢迎界面void fileadd();//读入文件,调用add函数,实现两个任意长整数的相加void directadd();//直接输入数字相加void calculayteadd();//实现两个任意长整数的相加int maincourse();//菜单选择void search();//查询文件中的数字(2)数据类型定义typedef struct linlist{Elemtype data;linlist * next;linlist * prior;} * LinList;(3)系统主要子程序详细设计本系统的各个函数之间的关系如下图:图31)菜单1代码void inputdata(){//调用input函数,实现两个任意长整数的输入system("cls");LinList L1=NULL,L2=NULL;printf("\t\t\t ------------------\n\t\t\t\t 输入数据\n\t\t\t ------------------\n");printf("输入第一个长整数:");input(L1); //调用input函数printf("输入第二个长整数:");input(L2);printf("\n数据将存放于文件中...");save(L1,L2); //调用save函数,存储L1L2FREE(L1);FREE(L2);//释放L1,L2printf("写入完成!\n");system("pause");}void input(LinList &L){//输入一个很长的整数到Lchar s[1000],s2[5]={'0','0','0','0','\0'};unsigned i=0,j;int sign=1,num=0,flag=1;Elemtype data;while(flag){flag=0;s[0]=getchar();if(s[0]=='-'){//若为负数sign=-1;i=i-1;}while(i==-1||s[i]!='\n'){//第一个输入负号或者输入数字i=i+1;s[i]=getchar();if(s[i]==',')i=i-1;else if((s[i]>'9'||s[i]<'0')&&s[i]!='\n'){printf("非法输入,请重新输入!\n");flag=1;continue;}}}s[i]=0;append(L,(int)(sign*ceil((strlen(s))/4.0)));//第一个结点存放链表长度和数据的正负号j=strlen(s)%4;i=0;if(j!=0){for(;i<j;i++)s2[i]=s[i];s2[i]=0;data=StrToPosiNum(s2);append(L,data);//以L为头结点,添加结点}for(;i<strlen(s);i=i+4){//每4位数放入一个结点for(j=0;j<4;j++)s2[j]=s[i+j];s2[j]=0;data=StrToPosiNum(s2);append(L,data);//以L为头结点,添加结点}}2)菜单2代码void calculayteadd(){//菜单2求和while(1){system("cls");printf("\n\t\t --------------------------------\n\t\t\t\t 加法运算\n");printf("\t\t --------------------------------\n");printf("\t\t\t\t1. 直接输入求和\n\t\t\t\t2. 读入文件求和\n\t\t\t\t3. 返回主菜单\n");printf("\t\t --------------------------------\n\n");char s[100];int flag=0;do{if(flag)printf("\t 输入非法,请重新输入:");elseprintf("\t 输入数字1-3选择:");flag=1;scanf("%s",s);}while(strlen(s)>1||s[0]-'0'<=0||s[0]-'0'>3);getchar();switch(s[0]-'0'){case 1:directadd();//直接输入数字求和break;case 2:fileadd();//输入文件名称求和break;case 3:return;break;}}void add(LinList &L1,LinList L2){//将L1与L2相加,结果放到L1LinList p,q,r;int cy=0;int sign1=1,sign2=1;if(!L1||L1->data==0)//若L1为空,相加结果为L2L1=L2;else if(!L2||L2->data==0)//若L2为空,相加结果为L1return;else{//否则if(abs(L1->data)<abs(L2->data)||L1->next->data<L2->next->data){ q=L1; //L1总是存放绝对值较大的数字L1=L2;L2=q;}p=L1->prior;q=L2->prior;if(L1->data<0)sign1=-1;if(L2->data<0)sign2=-1;if(sign1*sign2>0){ //相加的为同号数字while(p!=L1&&q!=L2){p->data=q->data+p->data+cy;if(p->data>9999){cy=1;p->data=abs(p->data)-10000;}elsecy=0;p=p->prior;q=q->prior;}while(p!=L1&&cy){p->data=p->data+cy;if(p->data>9999){cy=1;p->data=p->data-10000;}elsecy=0;p=p->prior;}p=p->next;if(cy){r=(LinList)malloc(sizeof(linlist));p->prior->next=r;r->prior=p->prior;r->next=p;p->prior=r;r->data=cy;L1->data=L1->data*sign1+1;L1->data=L1->data*sign1;}}else{//相加的为异号的数字cy=0;while(p!=L1&&q!=L2){p->data=p->data-cy;if(p->data<q->data){p->data=p->data+10000;cy=1;}p->data=p->data-q->data;p=p->prior;q=q->prior;}while(p!=L1&&cy){if(p->data<cy){cy=1;p->data=p->data+10000;}p->data=p->data-cy;p=p->prior;}}}while(L1->next->data==0&&L1->next->next!=L1){//结果为0的结点去掉p=L1->next;p->next->prior=L1;L1->next=p->next;L1->data=L1->data*sign1-1;L1->data=L1->data*sign1;Delete(p);}}3)菜单3代码void search(){//查询文件中的数字FILE * fp;LinList L1=NULL,L2=NULL;LinList p=L1;int i,length;char s[100];system("cls");printf("\t\t\t ------------------\n\t\t\t\t 文件查询\n\t\t\t ------------------");Elemtype t;printf("\n文件的名称为:");//读取文件scanf("%s",s);fp=fopen(s,"rb");fseek(fp,0,SEEK_SET);fread(&t,sizeof(Elemtype),1,fp);length=abs(t);//第一个数字的位数append(L1,t);for(i=0;i<length;i++){fread(&t,sizeof(Elemtype),1,fp);append(L1,t);}fread(&t,sizeof(Elemtype),1,fp);if(!feof(fp)){//读入第二个数字length=abs(t);append(L2,t);for(i=0;i<length;i++){fread(&t,sizeof(Elemtype),1,fp);append(L2,t);}printf("文件中有两个数字,分别为:\n");display(L1);putchar('\n');display(L2);putchar('\n');}else{printf("文件中有一个数字:\n");display(L1);putchar('\n');}system("pause");}3.3调试分析1.输入数据在主菜单下输入1并回车,进入子项1,可输入两个任意长的整数,保存于文件中,运行结果如图4所示。