⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 运算器.c

📁 数据结构课程设计_任意大数的加减乘运算器
💻 C
字号:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct node								//定义节点
{
	char data;
	struct node *next,*prior;
}lnode;
typedef struct									//定义链表,包含头尾指针及链表
{												//整数位,小数位长度
	lnode *head,*end;
	int before,after;
}list;
int b=0;
void initlist(list **L)
{
	(*L)=(list *) malloc(sizeof(list));
	(*L)->head=(lnode *) malloc(sizeof(lnode));
	(*L)->end=(lnode *) malloc(sizeof(lnode));
	(*L)->head->next=(*L)->end;
	(*L)->head->prior=NULL;
	(*L)->end->prior=(*L)->head;
	(*L)->end->next=NULL;
}
void after_increase(list *L,char c)				//完成从表尾插入字符c的操作
{
	lnode *p;
	p=(lnode*) malloc(sizeof(lnode));
	p->data=c;
	p->prior=L->end->prior;
	L->end->prior=p;
	p->prior->next=p;
	p->next=L->end;
}
void before_increase(list *L,char c)			//完成从表头插入字符c的操作
{
	lnode *p;
	p=(lnode *) malloc(sizeof(lnode));
	p->data=c;
	p->next=L->head->next;
	L->head->next=p;
	p->next->prior=p;
	p->prior=L->head;
}
void add_zero(list *L1,list *L2)				//加零函数,补零使两个数据的整数位和小数位的
{												//长度相同,以便加减时使小数点对齐
	while(L1->after>L2->after)
	{
		after_increase(L2,'0');
		L2->after++;
	}
	while(L2->after>L1->after)
	{
		after_increase(L1,'0');
		L1->after++;
	}
	while(L2->before<L1->before)
	{
		before_increase(L2,'0');
		L2->before++;
	}
	while(L2->before>L1->before)
	{
		before_increase(L1,'0');
		L1->before++;
	}
}
void sign(list *L,int n)						//加小数点的函数,使运算结果根据两个
{												//运算数据的小数位长度添加小数点
	lnode *p,*q;
	int i;
	p=L->end;
	for(i=1;i<=n;i++)
	{
		p=p->prior;
	}
		q=(lnode *) malloc(sizeof(lnode));
		q->data='.';
		q->prior=p->prior;
		q->next=p;
		p->prior=q;
		q->prior->next=q;
}
int compare(list *L1,list *L2)					//比较两个数据大小的函数
{
	lnode *p,*q;
	int temp;
	p=L1->head->next;
	q=L2->head->next;
	if(L1->before>L2->before)					//整数位不同
		temp=1;
	else
	{
		if(L2->before>L1->before)
			temp=-1;
		else
		{
			temp=p->data-q->data;				//整数位相同
			while(temp==0)
			{
				p=p->next;
				q=q->next;
				temp=p->data-q->data;
			}
		}
	}
	if(temp>0)
		return(1);
	else 
	{
		if(temp==0)
			return(2);
		else
			return(3);
	}
}
void copylist(list *L1,list *L2)				//保存数据函数,使L1中得到的数据保存在L2中
{
	lnode *q;
	char a;
	for(q=L2->head->next;q!=L2->end;q=q->next)
	{
		a=q->data;
		after_increase(L1,a);
	}
}
void clean(list *L)								//清空链表函数,将L清空
{
	L->head->next=L->end;
	L->end->prior=L->head;
}
void add(list **L1,list **L2,list *L3)			//加法运算
{
	lnode *p,*q;
	char a;
	int b=0;
	for(p=(*L1)->end->prior,q=(*L2)->end->prior;p!=(*L1)->head;p=p->prior,q=q->prior)
	{
		a=p->data+q->data-48+b;					//字符与整型差48
		b=0;									//b为进位
		if(a>'9')								//大于9需要进位
		{
			a=a-10;
			b=1;
		}
		before_increase(L3,a);					//将运算的结果插入链表
	}
	if(b)										//运算L1,L2最高位,如有进位
	{
		before_increase(L3,'1');
		L3->before++;
	}
}
void sub(list *L1,list *L2,list *L3)			//减法运算
{
	lnode *p,*q;
	char a;
	int	b=0;
	if(compare(L1,L2)==1)						//比较大小,保证是大数减小数
	{
		for(p=L1->end->prior,q=L2->end->prior;p!=L1->head;p=p->prior,q=q->prior)
		{
			a=p->data-q->data+48-b;
			b=0;								//b是借位标志
			if(a<'0')							//需要借位
			{
				a=a+10;
				b=1;
			}
			before_increase(L3,a);				//将结果插入链表
		}
	}
		else
		{
			sub(L2,L1,L3);						//如果L1数值大于L2,交换顺序
		}
}
void mult(list *L1,list *L2,list **L3)			//乘法运算
{
	lnode *p,*q;
	char a;
	int k;
	int m=0;									//m为一个开关
	list *temp1,*temp2;
	initlist(&temp1);							//temp1用来保存当前一位相乘的结果
	initlist(&temp2);							//temp2用来保存L2以前每位相乘后的结果的和
	temp2->after=0;
	for(q=L2->end->prior;q!=L2->head;q=q->prior)//L2每一位分别与L1相乘
	{
		temp1->before=0;
		for(p=L1->end->prior;p!=L1->head;p=p->prior)//L1每一位与L2当前位相乘
		{
			k=(p->data-48)*(q->data-48)+b;
			b=0;									//b是进位
			if(k>9)									//需要进位
			{
				b=k/10;
				a=k%10+48;
			}
			else
				a=k+48;
			before_increase(temp1,a);				//将结果插入链表
			temp1->before++;
		}
		if(b!=0)									//最高位有进位情况
		{
			a=b+48;
			before_increase(temp1,a);
			temp1->before++;
			b=0;
		}
		if(L2->end->prior==L2->head->next)			//如果L2仅有一位的情况
		{
			copylist((*L3),temp1);
			break;
		}
		else
		{
			if(m)									//L2已经超过两位与L1相乘,需要相加
			{
				copylist(temp2,*L3);				//将已有的结果保存在temp2中
				clean(*L3);
				temp2->after++;						//将temp2小数点左移,相当与
				temp2->before--;					//与L1错开一位
				temp1->after=0;
				add_zero(temp1,temp2);
				add(&temp1,&temp2,*L3);				//L2两位分别与L1相乘的结果相加
				clean(temp2);
				clean(temp1);
			}
			else									//L2当前仅有一位与L1相乘
			{
				copylist(*L3,temp1);
				temp2->before=temp1->before;
				clean(temp1);
			}
		}
		m=1;
	}
}
void cut(list *L)									//去掉运算多余的零函数
{
	lnode *p,*q;
	p=L->head->next;
	q=L->end->prior;
	while(p->data=='0')								//去掉整数部分的零
	{
		if(p->next->data=='.')
			break;
		else
		{
			L->head->next=p->next;
			p->next->prior=L->head;
			p=p->next;
		}
	}
	while(1)										//去掉小数部分的零
	{
		if(q->data=='.')							//小数部分全部为零的情况
		{
			q->prior->next=q->next;
			q->next->prior=q->prior;
			free(q);
			break;
		}
		if(q->data=='0')
		{
			L->end->prior=q->prior;
			q->prior->next=L->end;
			q=q->prior;
		}
		else
			break;
	}
}
int judge(list *L)									//判断L的数据是否是零的函数
{
	lnode *p;
	int a=0;
	for(p=L->head->next;p!=L->end;p=p->next)
	{
		if(p->data!='0')
		{
			a=1;
			break;
		}
	}
	if(a)
		return(1);
	else
		return(0);
}
void readnum(char filename[],list *L)			//从文件读取数据函数,并记录整数位,小数位个数
{
	FILE *fp;
	char c;
	int n=0;
	int m=1;
	L->before=0;
	L->after=0;
	fp=fopen(filename,"r");
	while(!feof(fp))
	{
		c=fgetc(fp);
		if(c>='0'&&c<='9'||c=='.'||c=='-')		//读完最后一位还要相下读取一位,故要舍去
		{
			if(c=='.')							//小数点不读取
			{
				m=0;
				continue;
			}
			if(c=='-')							//负号不读取
			{
				before_increase(L,c);
				continue;
			}
			if(m)
			{
				after_increase(L,c);
				L->before++;
			}
			if(!m)
			{
				after_increase(L,c);
			    L->after++;
			}
		}
		else
			break;
	}
	fclose(fp);
}
int freesign(list *L)					//取数的绝对值函数
{
	lnode *p;
	p=L->head->next;
	if(p->data=='-')
	{
		p=L->head->next;
		L->head->next=p->next;
		p->next->prior=L->head;
		p->next=p;
		p->prior=p;
		free(p);
		return(1);
	}
	else 
		return(0);
}
void writenum(char filename[],list *L)	//将结果写入文件函数
{
	FILE *fp;

	char c;
	lnode *p;	
	fp=fopen(filename,"w");
	for(p=L->head->next;p!=L->end;p=p->next)
	{
		c=p->data;
		fputc(c,fp);
	}
	fclose(fp);
}
void main()
{
	list *L1,*L2,*L3;
	int sign1=0,sign2=0;
	int com;
	char filename1[10],filename2[10];
	char filename3[]="add.txt";
	char filename4[]="sub.txt";
	char filename5[]="mult.txt";
	initlist(&L1);								//第一个数据
	initlist(&L2);								//第二个数据
	initlist(&L3);								//运算结果

	printf("input the first file's name");
	gets(filename1);
	printf("input the second file's name");
	gets(filename2);
	readnum(filename1,L1);						//将第一个数据保存在L1中
	readnum(filename2,L2);						//将第二个数据保存在L2中
	sign1=freesign(L1);							//取L1的绝对值,并判断正负
	sign2=freesign(L2);							//取L2的绝对值,并判断正负
	com=compare(L1,L2);							//比较L1,L2绝对值大小
	if(sign1==0&&sign2==0)						//L1,L2都是正数情况
	{
		if(judge(L1)&&judge(L2))
		{
			mult(L1,L2,&L3);
			sign(L3,(L1->after+L2->after));
			cut(L3);
		}
		else
			before_increase(L3,'0');
		writenum(filename5,L3);
		clean(L3);
		add_zero(L1,L2);
		add(&L1,&L2,L3);
		sign(L3,L1->after);
		cut(L3);
		writenum(filename3,L3);
		clean(L3);
		if(com!=2)
		{
			sub(L1,L2,L3);
			if(com==3)
				before_increase(L3,'-');
			sign(L3,L1->after);
			cut(L3);
		}
		else
			before_increase(L3,'0');
		writenum(filename4,L3);
		clean(L3);
		
	}
	if(sign1==1&&sign2==1)					//L1,L2都是负数情况
	{
		if(judge(L1)&&judge(L2))
		{
			mult(L1,L2,&L3);
			sign(L3,(L1->after+L2->after));
			cut(L3);
		}
		else
			before_increase(L3,'0');
		writenum(filename5,L3);
		clean(L3);
		add_zero(L1,L2);
		add(&L1,&L2,L3);
		sign(L3,L1->after);
		cut(L3);
		before_increase(L3,'-');
		writenum(filename3,L3);
		clean(L3);
		if(com!=2)
		{
			sub(L1,L2,L3);
			sign(L3,(L1->after,L2->after));
			cut(L3);
			if(com==1)
				before_increase(L3,'-');
		}
		else
			before_increase(L3,'0');
		writenum(filename4,L3);
		clean(L3);
	}
	if(sign1==0&&sign2==1)                 //L1为正,L2为负情况
	{
		
		if(judge(L1)&&judge(L2))
		{
			mult(L1,L2,&L3);
			sign(L3,(L1->after+L2->after));
			cut(L3);
			before_increase(L3,'-');
		}
		else
			before_increase(L3,'0');
		writenum(filename5,L3);
		clean(L3);
		add_zero(L1,L2);
		if(com!=2)
		{
			sub(L1,L2,L3);
			sign(L3,L1->after);
			cut(L3);
			if(com==3)
				before_increase(L3,'-');
		}
		else
			before_increase(L3,'0');
		writenum(filename3,L3);
		clean(L3);
		add(&L1,&L2,L3);
		sign(L3,L1->after);
		cut(L3);
		writenum(filename4,L3);
		clean(L3);
	}
	if(sign1==1&&sign2==0)					//L1为负,L2为正情况
	{
		if(judge(L1)&&judge(L2))
		{
			mult(L1,L2,&L3);
			sign(L3,(L1->after+L2->after));
			cut(L3);
			before_increase(L3,'-');
		}
		else
			before_increase(L3,'0');
		writenum(filename5,L3);
		clean(L3);
		add_zero(L1,L2);
		if(com!=2)
		{
			sub(L1,L2,L3);
			sign(L3,L1->after);
			cut(L3);
			if(com==1)
				before_increase(L3,'-');
		}
		else
			before_increase(L3,'0');
		writenum(filename3,L3);
		clean(L3);
		add(&L1,&L2,L3);
		sign(L3,L1->after);
		cut(L3);
		before_increase(L3,'-');
		writenum(filename4,L3);
		clean(L3);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -