标签:程序 返回 lis efi lib 检查 ext 目的 ring
一、实验内容
【问题描述】 设计一个实现任意长的整数进行加法运算的演示程序 。
【基本要求】 利用双向循环链表实现长整数的存储,每个结点含一个整形变量。输入和输出形式:按中国对于长整数的表示习惯,每四位一组,组间用逗号隔开。
【测试数据】
(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;
} 
标签:程序 返回 lis efi lib 检查 ext 目的 ring
原文地址:https://www.cnblogs.com/liulangbxc/p/11690969.html