实验:线性表及其应用

一、实验内容

【问题描述】 设计一个实现任意长的整数进行加法运算的演示程序

【基本要求】 利用双向循环链表实现长整数的存储,每个结点含一个整形变量。输入和输出形式:按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开。

【测试数据】

100;应输出“0”

2-2345,6789-7654,3211;应输出“-1,0000,0000”

3-9999,99991,0000,0000,0000;应输出“9999,0000,0001”

41,0001,0001-1,0001,0001;应输出“0”

51,0001,0001-1,0001,0000;应输出“1”

6-9999,9999,9999-9999,9999,9999;应输出-1,9999,9999,9998”

71,0000,9999,99991;应输出“1,0001,0000,0000”

二、实验目的

熟悉掌握链表的基本操作

.培养运用线性表解决问题的能力。

三、实验文档:

1. 概要设计(文字性地说明解决问题的具体方法和步骤)

a) 创建双向链表结点的结构体

b) 声明三条链表:L1L2L

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;
}

 

  感谢阅读!

posted @ 2019-10-17 11:29  叶际参差  阅读(476)  评论(0编辑  收藏  举报