课设(一)任意长整数的加减法

1.简介

这里是一个苦逼大学生的自述,第一次写blog,内容是课设的三个题目,由于能力有限,编写代码的过程中也参考了网络上的代码,有不足的地方希望大家可以指出来,如果可以帮助到大家也是我的荣幸。最近和学长一起参加智能车比赛,有空会把自己调试的心得写在博客上,以后也会更新一些自己做的小项目。

2.代码

a.头文件及宏定义

#include "iostream.h"
#include "stdlib.h"
#include "stdio.h"
#include "ctype.h"
#include "conio.h"

#define OK true
#define ERROR false

b.子程序

(1)双向链表的定义及操作

//定义双向链表的节点
typedef struct node
{
	int dat;//数据域
	node *pre;//左孩子
	node *next;//右孩子
}node,*list;//tnode可用于反映节点所需的存储空间

//初始化符号节点
node* initlist(int key)
{
	node* l = (node*)malloc(sizeof(node)); //分配存储空间
	if ( l == NULL) 
		exit(0);
	l->dat = key;
	l->next = l; 
	l->pre = l;
	return l;
}

//	删除节点
void Delete(list& a,node* p)
{
	p->pre->next=p->next;
	p->next->pre=p->pre;
	free(p);
}

//前插
void insertfront(list& a,int key)//用于存储输入 插入在节点a前面//输入数据以负数-321为例:(-1)3<-2<-1<-{(-1)} 
{
	node* s;
	s = initlist(key);
	s->next = a; 
	s->pre = a->pre;
	a->pre->next=s;
	a->pre=s;	 
}

//后插
void insertback(list& a,int key)//用于存储输出(计算结果由低位向高位输出)例-321:{(-1)} -> 3 ->2 ->1(-1)
{
	node* s;
	s = initlist(key);
	s->next=a->next;
	s->pre=a;
	a->next->pre=s;
	a->next=s;
}

(2)整数的输入输出

node* inputdata()//输入整数
{
	int Data;//存储数据
	char c;//表示符号
	node* l;//存储的链表
	l=initlist(0);
	printf("按格式输入数据:-1234,5678,1234\n");
	if((c=getchar())=='-')//输入负数 用-1存储符号
		l=initlist(-1);
	else
		l=initlist(1);
	if(isdigit(c))//输入正数时没有加正号
		ungetc(c,stdin);//退格处理
	do //输入数据以负数-321为例:(-1)3 2 1{(-1)} 
	{
		scanf("%d",&Data);
		insertfront(l,Data);
	} while((c=getchar())!='\n');
	printf("你输入的数为:");
	printlist(l);
	return l;
}
void printlist(list a)//输出整数
{
	node* p=a;
	if (p->dat==-1)
	{
		printf("-");
	}
	p=p->next;
	printf("%d",p->dat);//首位数据空位不需要0
	p=p->next;
	while(p!=a)//环形存储结构 符号位-数据域-符号位
	{
		if(p->dat<10)
			printf(",000");
		else if(p->dat<100)
			printf(",00");
		else if(p->dat<1000)
			printf(",0");
		else
			printf(",");
		printf("%d",p->dat);
		p=p->next;
	}
}

(3)同号加法与异号加法

//同号加法
void Add(list& a,list& b,list& c)// c的初始符号为a的符号
{ 
	list pa,pb;
	pa=a->pre;
	pb=b->pre;
	int carry=0,tmp;//carry存储进位 tmp存储当前节点之和
	c=initlist(1);
	while ((pa!=a)&&(pb!=b))//位数相同时
	{
		tmp=pa->dat+pb->dat+carry;
		if(tmp>=10000)//产生进位
		{
			carry=1;
			tmp-=10000;
		}
		else
		{
			carry=0;
		}
		insertback(c,tmp);
		pa=pa->pre;
		pb=pb->pre;
	}
	while (pa!=a)//a位数比b大
	{
		tmp=pa->dat+carry;
		if (tmp>=10000)
		{
			carry=1;
			tmp-=10000;
		}
		else
		{
			carry=0;
		}
		insertback(c,tmp);
		pa=pa->pre;
	}
	while (pb!=b)//b位数比a大
	{
		tmp=pb->dat+carry;
		if (tmp>=10000)
		{
			carry=1;
			tmp-=10000;
		}
		else
		{
			carry=0;
		}
		insertback(c,tmp);
		pb=pb->pre;
	}
	if (carry!=0)
	{
		insertback(c,1);
	}
}

//异号加法
void sub(list& a,list& b,list& c)// c的初始符号为b的符号
{
	node* pa=a->pre;
	node* pb=b->pre;
	node* pc;
	int borrow=0,tmp;//borrow为后一位向当前位的借位
	while ((pa!=a)&&(pb!=b))//假设a的绝对值比b大 c=a-b
	{
		if ((pa->dat-borrow)>=pb->dat)//被减数借位后仍大于减数 不产生借位
		{
			tmp=(pa->dat-borrow)-pb->dat;
			borrow=0;
		}
		else//产生借位
		{
			tmp=(10000+pa->dat-borrow)-pb->dat;
			borrow=1;
		}
		insertback(c,tmp);
		pa=pa->pre;
		pb=pb->pre;
	}
	if (  (pa!=a) || ((pa==a)&&(pb==b)&&(borrow==0)) )//被减数长于减数 或 长度相等且不产生借位 
	{
		c->dat=a->dat;//设置符号位
	}
	if (c->dat!=a->dat)//运算顺序出错 b的绝对值比a大 c=a-b将a-b修改为b-a
	{
		pc=c->pre;
		while (pc!=c)
		{
			if(pc==c->pre)
			{
				pc->dat=10000-pc->dat;//最低位修改前后和为10000
			}
			else
			{
				pc->dat=9999-pc->dat;//其余位修改前后和为10000
			}
			pc=pc->pre;
		}
		borrow=borrow?0:1;//将当前的借位取反
		while (pb!=b)
		{
			if (pb->dat>=borrow)
			{
				tmp=pb->dat-borrow;
				borrow=0;
			}
			else
			{
				tmp=pb->dat+10000-borrow;//
				borrow=1;
			}
			insertback(c,tmp);
			pb=pb->pre;
		}
	}
	else//运算顺序正确 a的绝对值比b大
	{
		while (pa!=a)
		{
			if (pa->dat>=borrow)
			{
				tmp=pa->dat-borrow;
				borrow=0;
			}
			else
			{
				tmp=pa->dat+10000-borrow;//
				borrow=1;
			}
			insertback(c,tmp);
			pa=pa->pre;
		}
	}
	pc=c->next;//首部清除多余的0
	while (pc->next!=c&&pc->dat==0)
	{
		pc=pc->next;
		Delete(c,pc->pre);
	}
}

//做加法
list addlist(list& a, list& b)
{
	node* c;
	if(a->dat*b->dat>0)//同号加法
	{
		c=initlist(a->dat);
		Add(a,b,c);
	}
	else
	{
		c=initlist(b->dat);//异号加法
		sub(a,b,c);
	}
	return c;
}

//做减法
list sublist(list& a, list& b)
{
	node* c;
	b->dat*=-1;//改变减数符号
	if(a->dat*b->dat>0)//同号加法
	{
		c=initlist(a->dat);
		Add(a,b,c);
	}
	else
	{
		c=initlist(b->dat);//异号加法
		sub(a,b,c);
	}
	return c;
}

c.主程序

这一段写的很烂,但是不想改了。。。。

void main()
{

	int key;
	while (1)
	{
		list a,b,c;
		a=inputdata();
		printf("\n");
		b=inputdata();
		printf("\n");
		printf("做加法输入1,做减法输入0\n");
		scanf("%d",&key);
		if(key==1)
		{
			c=addlist(a,b);
			printlist(a);
			printf("+");
			printlist(b);
			printf("=");
			printlist(c);
			printf("\n");
		}
		else
		{
			c=sublist(a,b);
			printlist(a);
			printf("-");
			printlist(b);
			printf("=");
			printlist(c);
			printf("\n");
		}
	}
}

  • 4
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值