课 程设计报告
科 目 :
数 据 结 构
姓 名 :
雷 杰
学 号 : 2 0 1 3 0 3 0 1 0 3 0 2 0
班 级 : 2 0 1 3 0 0 0 1 0 1
学 院 : 英 才 实 验 学 院
实验 长整数四则运算
一、实验目的
运用线性表來存储高精度长整数,并进行长整数的加法,减法以及乘法运算。
二、实验要求
设计一个程序来实现 100 位以内长整数的加,减,乘运算,并且在输入和输出过程中,
每四位整数用逗号来隔开。
三、实验思想
实验中采用双向链表存储长整数,长整数的每四位存储在一个链表的一个结点之中。
双向链表结点以及表头定义如下。
typedef struct Node{
int data;
struct Node *next;
struct Node *prior;
}Node;
typedef struct FrontNode{
int NodeCount;
//记录节点个数
int sign;
//表示长整数符号
Node *head;
Node *tail;
}DuLink;
在进行运算的时候,先用 CompInt()函数对输入的两个长整数的绝对值进行大小的比较,
以便于以后实现绝对值较大数减去较小数的操作。这也是本程序的一个特点。在绝对值的加
法部分,用 int 型变量 inc 存储进位操作。在绝对值的减法部分,用 int 型变量 dec 实现借位
操作。加法和减法的操作分别依据引入减号之后两个长整数的符号是否相同而采取了进行绝
对值相加减的操作,并且将绝对值大的数字的符号传递给结果得到的数字。乘法部分使用二
重循环并结合加法进行。用一个链表中的结点依次乘以另一个链表的结点,用 long 型变量
m 实现进位操作,并将此计算的结果存储于一个新链表 1 之中。然后每一轮都用 int 型变量
i 计数,根据 i 的数值对每一轮链表的结果进行调整。每一轮结束之后,新链表 1 的结果与
新链表 2 相加后存储在新链表 2 中。
四、实验中的函数释义
本程序设计过程中使用了模块化程序设计方法,对主要操作以及重复性操作进行了函数
化封装,以便于后期维护。
1.Input( )函数:输入时采用一个 char 类型变量逐个字符进行读取,并根据数字与其对
应字符 ASCII 码的关系转换为整型变量保存在双向链表中。在此一开始对符号位进行判断。
2.Output()函数:结果的输出,对不足四位的结点数值进行了补零操作,实现每隔四位
的输出
3.Count()函数:对链表中的结点个数进行判断,并将结果存储在相应链表的 NodeCount
下
4.CompInt()函数:对两个长整数的绝对值大小进行判断,为绝对值加减操作做预处理。
5.CopyInt()函数:复制链表
6.AbsAddInt()函数:实现绝对值相加
7.AbsSubInt()函数:实现绝对值相减
8.MulInt()函数:实现乘法
9.Main()函数:调动其余函数,组成完整程序,实现长整数加减乘运算.
五、反思与总结
1. 读取输入数值的顺序:起初设计算法时,因为错误理解了数值输入顺序,导致数字的
高位和地位出现颠倒的情况.
2. 指针初始化的问题:因为对初始化的意义不是特别理解,未对部分链表进行初始化操
作,程序执行时出现野指针的情况.
3. 学会了 Debug:起初不会使用调试程序,走了许多弯路,在和同学交流时学会了使用
Debug 进行调试.
4. 对线性表,指针以及 malloc 函数的概念有了更深刻的理解.
5. 体验到了模块化设计程序的优点:便于维护,节省空间.
6. 体会到了编程带来的乐趣,虽然这次我花了接近一周的时间才完成整个程序的编写,
但整个过程中解决问题,然后看着程序正确运行所带来的快乐却是无法替代的.
7. 更加明白了与同学老师交流学习的意义.
六、程序运行结果图
1.
加法
2. 减法
3. 乘法
七、关键程序代码
1. 绝对值加法
void AbsAddInt(DuLink *h1,DuLink *h2,DuLink *h3){
//h1 绝对值?
Node *p=h1->head;
Node *q=h2->head;
Node *s,*t;
h3->sign=h1->sign;
h3->head=NULL;
int inc=0;
while(q){
t=(Node*)malloc(sizeof(Node));
t->data=p->data+q->data+inc;
inc=t->data/10000;
t->data=t->data%10000;
if(h3->head==NULL){
//新得到的结点插入 h3
h3->head=t;
t->next=NULL;
s=t;
s->prior=NULL;
}
else{
s->next=t;
t->prior=s;
s=t;
s->next=NULL;
}
p=p->next;
q=q->next;
}
while(p){
//q 中结点此时已加完
t=(Node*)malloc(sizeof(Node));
t->data=p->data+inc;
inc=t->data/10000;
t->data=t->data%10000;
s->next=t;
t->prior=s;
t->next=NULL;
s=t;
p=p->next;
}
if(inc!=0){
//p,q 中结点都已经完结
t=(Node*)malloc(sizeof(Node));
t->data=inc;
s->next=t;
t->prior=s;
s=t;
s->next=NULL;
}
h3->tail=s;
Count(h3);
}
2. 绝对值减法
void AbsSubInt(DuLink *h1,DuLink *h2,DuLink *h3){
//h1 绝对值大于
h2
h3->sign=h1->sign;
Node *p=h1->head;
Node *q=h2->head;
Node *s,*t;
h3->head=NULL;
int dec=0;
while(q){
t=(Node*)malloc(sizeof(Node));
if(p->data-dec>=q->data)
t->data=p->data-q->data-dec;
else{
t->data=10000+p->data-q->data-dec;
dec=1;
}
if(h3->head==NULL){
//新得到的结点插入 h3
h3->head=h3->tail=t;
t->prior=NULL;
t->next=NULL;
s=t;
}
else{
s->next=t;
t->prior=s;
s=t;
s->next=NULL;
h3->tail=s;
}
p=p->next;
q=q->next;
}
while(p){
//q 中结点此时已减完
t=(Node*)malloc(sizeof(Node));
t->data=p->data-dec;
if(p->data-dec>=0)
t->data=p->data-dec;
else{
t->data=10000+p->data-dec;
dec=1;
}
s->prior=t;
t->next=s;
s=t;
p=p->prior;
s->prior=NULL;
}
h3->head=s;
//删除链表前面值为 0 的结点
p=h3->head;
if(p->next!=NULL)
//当 p==h->tail 时结束循环
while(p->data==0){
q=p;
p=p->next;
p->prior=NULL;
free(q);
}
h3->head=p;
Count(h3);
}
3. 乘法
void MulInt(DuLink *h1,DuLink *h2,DuLink *h3){
//h1 绝对值大
Node *p=h1->head;