实验:线性表及其应用
一、实验内容
【问题描述】 设计一个实现任意长的整数进行加法运算的演示程序 。
【基本要求】 利用双向循环链表实现长整数的存储,每个结点含一个整形变量。输入和输出形式:按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开。
【测试数据】
(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”。
二、实验目的
1.熟悉掌握链表的基本操作。
2.培养运用线性表解决问题的能力。
三、实验文档:
1. 概要设计(文字性地说明解决问题的具体方法和步骤)
a) 创建双向链表结点的结构体
b) 声明三条链表:L1,L2,L
c) 每一个结点的数据域只存四位数
d) 链表的生长方向为顺序,相加时逆序,即由尾到头,头结点存储符号和位数信息
e) 每一次相加时,若符号相同,则直接相加,用n=data/1,0000检查是否进位,若进位(n>1),L1链的前一结点data+1,;
f) 若符号相异,则绝对值大的作为被减数,事后确定符号,借位时,若果前一结点不是 head,则data=1 0000+v1+v2,当其中一条链已经加完后,直接把剩下的接在L链上
g) 结果的符号与绝对值大的相同
h) 相加时,如果一些结点的data归零了,则要删除,这一步需在完成所有相加运算后进行
i) 用while语句控制输出
DulNode.h #ifndef DULNODE_H #define DULNODE_H #include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct DulNode{ //结点类型,双向链表 int data; struct DulNode *prior; struct DulNode *next; }DulNode; void listCreate(DulNode *L,int n) /*创建链表*/ { /*传入链表头结点,所需结点个数*/ /*创建空链表*/ int i; DulNode *p,*q; p=L; for(i=0;i!=n;i++) { q=(DulNode*)malloc(sizeof(DulNode)); p->next=q; q->prior=p; p=q; } q->next = NULL; /*尾结点的next指向next*/ } void destroyList(DulNode *L) /*销毁链表*/ { /*传入头结点删除链表*/ DulNode *p,*q; p=L; q=L; while(q!=NULL) { q=p->next; free(p); p=q; } } int input(DulNode *L,char *s) /*输入*/ { /*传入链表头结点和数字字符串*/ /*先对字符串处理*/ char *p,*ad; DulNode *q=NULL; int i,t,n,length,wei,data[20]; /*总长和位数(不含符号),data[]记录数据*/ length=strlen(s); n=length/5; if(length%5!=0) n += 1; /*4位数为一组,有n组*/ wei=length - n +1; /*不算逗号*/ listCreate(L,n); /*创建链表*/ /*头结点data记录符号和位数*/ L->data = wei; /*对正数的处理*/ p=s; if(s[0]=='-') /*对负数的处理*/ { wei -= 1; L->data = -1 * wei; p=s+1; } /*开始将字符串变为数字*/ for(i=0;i!=length;i++) /*改逗号分隔为终止符分隔*/ { if(s[i]==',') s[i]='\0'; } ad = p; data[0]=atoi(ad); for(i=1;i!=n;i++) /*n为组数*/ { for(;*ad!='\0';ad++); data[i]=atoi(++ad); /*记录每组数*/ } q=L->next; i=0; while(q!=NULL) /*总算存进去了*/ { q->data = data[i]; q=q->next; i++; } return n; /*返回有效结点个数,即不包括头结点*/ } void add(DulNode *L1,DulNode *L2,DulNode *L,DulNode *pad) /*相加并输出*/ { /*要求L1的位数大于L2*/ /*传入已经创建好并录入数据的两个加数链表的头结点*/ /*和一个即将存储最终结果的链表的头结点*/ int carry=0,borrow=0; /*进位和借位*/ int m=0; /*记录组数*/ DulNode *Lp1=L1,*Lp2=L2,*q=NULL; /*从后面开始*/ while(Lp1->next!=NULL) { Lp1=Lp1->next; m++; } while(Lp2->next!=NULL) Lp2=Lp2->next; /*完善结果链表*/ listCreate(L,m+2); L->data=1; /*只把符号记下来*/ if(L1->data < 0) L->data = -1; /*-1代表负号*/ /*Lp1,Lp2都指向最后结点,开始相加*/ q = L->next; if(L1->data * L2->data >= 0) /*同号直接相加*/ { while(Lp1!=L1 && Lp2!=L2) { q->data = Lp1->data + Lp2->data + carry; carry = q->data / 10000; q->data = q->data % 10000; /*进一*/ q=q->next; Lp1=Lp1->prior; Lp2=Lp2->prior; } while(Lp1!=L1) /*已传入的L1位数更大规定*/ { q->data = Lp1->data + carry; carry = q->data / 10000; q->data = q->data % 10000; /*进一*/ q=q->next; Lp1=Lp1->prior; } if(carry != 0) { q->data = carry; q=q->next; } } else if(L1->data * L2->data < 0) /*异号大数减小数*/ { while(Lp1!=L1 && Lp2!=L2) { q->data = 10000 + Lp1->data - Lp2->data - borrow; if(q->data / 10000 == 0) borrow = 1; else borrow = 0; q->data = q->data % 10000; q=q->next; Lp1=Lp1->prior; Lp2=Lp2->prior; } while(Lp1 != L1) { q->data = Lp1->data - borrow; if(borrow != 0) { q->data += 10000; if(q->data / 10000 == 0) borrow = 1; else borrow = 0; q->data = q->data % 10000; } q=q->next; Lp1=Lp1->prior; } } /*记录最终位置,方便从后往前输出*/ pad = q->prior; while(pad->data == 0 && pad->prior != L) pad=pad->prior; printf("%d",L->data * pad->data); while(pad->prior != L) { pad=pad->prior; printf(",%04d",pad->data); //自动加0 /* if(pad->prior != L) printf(",");*/ } } #endif 测试: main.h #include "Dulnode.h" int main() { DulNode *L1,*L2,*L,*pad; char s1[80],s2[80]; int m,n; L1 = (DulNode*)malloc(sizeof(DulNode)); L2 = (DulNode*)malloc(sizeof(DulNode)); L = (DulNode*)malloc(sizeof(DulNode)); printf("绝对值大的先输入:\n"); gets(s1); gets(s2); m = input(L1,s1); n = input(L2,s2); /*返回有效结点个数,即不包括头结点*/ add(L1,L2,L,pad); return 0; }
感谢阅读!