任意长的整数加减法运算

该博客介绍了如何设计一个算法,使用链表存储任意长度的整数并进行加减法运算。通过双向循环链表结构,处理每四位一组的输入数字,确保整型变量在特定范围内。文章还强调了友好的用户界面和错误处理功能,以及在输出时单独处理正负符号的方法。运行环境为Dev C++。
摘要由CSDN通过智能技术生成

题目要求:设计算法,实现一个任意长的整数进行加法、减法运算的演示程序。例如:1234,5123,4512,3451,2345与-1111,1111,1111,1111,1111的加法结果为:0123,4012,3401,2340,1234。基本要求如下:
(1) 利用链表实现长整数的存储,每个节点含一个整型变量;
(2) 整型变量的范围:-(2^15 -1)~(2^15 -1);
(3) 输入与输出形式每四位一组,组间用逗号分隔开。如:1986,8213,1935,2736,3299;
界面友好,每步给出适当的操作提示,并且系统具有一定的容错能力。

需求分析:

  1. 长整数运算中长整数的输入包含正负符号和四位一个逗号隔开,存储过程中利用输入定义一个char类型将符号存入以及将逗号忽略,不存入链表的结点中。
  2. 因链表需要进行多次遍历判断和处理,这里采用双向循环链表来存储长整数,方便后续进行运算。
  3. 链表内各结点的数据加减采用无符号式进行。
  4. 符号加减判断采用另外判断的方式进行正负符号加减判断。
  5. 输出结果正负号不在链表内进行,数据输出采用链表遍历方式边判断边进行数据输出。
  6. 运行环境:dev c++。
#include<iostream>
#include<stdlib.h>
using namespace std;

char finalsym;

typedef struct ListNode{		//结构体,双向循环链表 
	int data;
	struct ListNode *pre;
	struct ListNode *next;
}Node,*List;
 
void Init(List &L){		//双向循环链表的初始化 

	L = new Node;
	if(L){
		L->pre=L;
		L->next=L;
	}	
	else
		exit(0);
}

void Create(List &L, int &n){		//双向循环链表的建立,返回结点数n,留作下面比绝对值 
	int x;
	char d;
	List p=L;
	cin>>x;
	while((d=getchar())!='\n'){  //循环输入数值,遇到回车结束。 
		List q=new Node;
		n++;
		q->data=x;
		q->pre=p;
		q->next=L;
		p->next=q;
		L->pre=q;
		p=q;
		cin>>d;
		cin>>x;
	}
	    List q=new Node;  //将回车前输入的x值存入链表的结点。 
		n++;
		q->data=x;
		q->pre=p;
		q->next=L;
		p->next=q;
		L->pre=q;
		p=q;
}

void ListInsertT(List &L, int e){ //头部插入数值e 
	List s=new Node;
	s->data=e;
	s->next=L->next;
	s->pre=L;
	L->next->pre=s;
	L->next=s;
} 

void ListInsertW(List &L, int e){ //尾部插入数值e 
	List s=new Node;
	s->data=e;
	s->next=L;
	s->pre=L->pre;
	L->pre->next=s;
	L->pre=s;	
}

int Compare(List &L1,List &L2, int &n1, int &n2){   //绝对值比较两数大小  返回1代表L1>L2,返回-1代表L1<L2,返回0代表L1=L2; 
	if(n1>n2) return 1;
	else if(n1<n2) return -1;
	else {
		List p,q;
		p=L1->next;
		q=L2->next;
		while(p!=L1&&q!=L2&&p->data==q->data){
				p=p->next;
				q=q->next;
		}
		if(p->data>q->data) return 1;
		else if(p==L1) return 0;
		else return -1;
	}
}

void sub(List &L1,List &L2,List &L3){    //减法 
	List p=new Node;
	List q=new Node;
	int e;
	int jiewei=0;
	p=L1->pre;
	q=L2->pre;
	while(p!=L1&&q!=L2){ //L1,L2长度相等 
		e=p->data-q->data-jiewei;
		if(p->data < q->data){
			e=e+10000;
			jiewei=1;
		}
		else {
			jiewei=0;
		}
		ListInsertT(L3,e);
		p=p->pre;
		q=q->pre;
	} 
	while(p!=L1){ //L1比L2长 
		e=p->data-jiewei;
		if(e<0) {
			e=e+10000;
			jiewei=1;
		}
		else jiewei=0;
		ListInsertT(L3,e);
		p=p->pre;
	}
	while(q!=L2){ //L2比L1长 
		e=q->data-jiewei;
		if(e<0) {
			e=e+10000;
			jiewei=1;
		}
		else jiewei=0;
		ListInsertT(L3,e);
		q=q->pre;
	} 
}

void add(List &L1,List &L2,List &L3){	//加法 
	List p=new Node;
	List q=new Node;
	int e;
	int jinwei=0;
	p=L1->pre;
	q=L2->pre;
	while(p!=L1&&q!=L2){ //L1,L2长度相等 
		e=p->data+q->data+jinwei;
		if(e>=10000){
			jinwei=1;
			e=e-10000;			
		}
		else jinwei=0;
		ListInsertT(L3,e);
		p=p->pre;
		q=q->pre;
	}
	while(p!=L1){ //L1比L2长 
		e=p->data+jinwei;
		if(e>=10000){
			jinwei=1;
			e=e-10000;			
		}
		else jinwei=0;
		ListInsertT(L3,e);
		p=p->pre;
	} 
	while(q!=L2){ //L2比L1长 
		e=q->data+jinwei;
		if(e>=10000){
			jinwei=1;
			e=e-10000;			
		}
		else jinwei=0;
		ListInsertT(L3,e);
		q=q->pre;
	}
	if(jinwei==1) ListInsertT(L3,1);
}

void Select(List &A,List &B,List &C,int &n1, int &n2, char &sym1, char &sym2){  //运算方法判断选择 
	char symbol;
	cin>>symbol;
	int num=Compare(A,B,n1,n2);
	if(symbol=='+'){
		if(sym1=='+'&&sym2=='+'){
			//a+b算法 
			finalsym='+';
			add(A,B,C);
		}else if(sym1=='+'&&sym2=='-'){
			//compare A,B 
			if(num==1){            //A>B
			//a-b
			finalsym='+';    
			sub(A,B,C);
			}else if(num==-1){        //B>A
			//-(b-a)
			finalsym='-';
			sub(B,A,C);
			}else sub(A,B,C);
		}else if(sym1=='-'&&sym2=='+'){
			//compare A,B
			if(num==1){     //A>B:-(a-b)
			   finalsym='-';
			   sub(A,B,C);
			}else if(num==-1){    //B>A:b-a
			   finalsym='+';
			   sub(B,A,C);
		   }else sub(A,B,C);
		}else if(sym1=='-'&&sym2=='-'){
			//-(a+b)算法 
			finalsym='-';
			add(A,B,C);
		}
	}else if(symbol=='-'){
		if(sym1=='+'&&sym2=='+'){      
			//compare A,B
			if(num==1){         //A>B: a-b
			    finalsym='+';
			    sub(A,B,C);
		    }
			else if(num==-1){    //B>A: -(b-a)
			    finalsym='-';
			    sub(B,A,C);
	    	}else sub(A,B,C);
		}else if(sym1=='+'&&sym2=='-'){
		    //a+b
		    finalsym='+';
		    add(A,B,C);
		}else if(sym1=='-'&&sym2=='+'){
			//-(a+b)算法 
			finalsym='-';
			add(A,B,C);
		}else if(sym1=='-'&&sym2=='-'){
			//compare A,B
			if(num==1){      //A>B:-(a-b)
			    finalsym='-';
			    sub(A,B,C);
		    }
			else if(num==-1){    //B>A:b-a
			   finalsym='+';
			    sub(B,A,C);
		   }else sub(A,B,C);
		}
	}else{
		cout<<"输入错误,请重新输入:"<<endl; 
		Select(A,B,C,n1,n2,sym1,sym2);
	}
}

void Show(List &L){ //输出结果 
	Node *p;
 	if(NULL == L) return;
 	p=L->next;
 	while(p->data==0&&p->next!=L){  //结果中遇到数据为0的结点直接略过不输出,直到有数值的结点或尾节点 
 		p=p->next;
	 }
	 if(p->data==0&&p->next==L) {  //如果结果链表中数据全为0 
	 	cout<<"0";
	 	return;
	 }
	 cout<<p->data;  //第一个数作直接输出,无需在前添0; 
	 p=p->next;
	 if(p==L) return;  //如果p此时指向最后一个数 ,p->next为null,结束输出。 
	 else cout<<",";
 	while (1){       //循环输出剩余结点内容。 
 		if(p->data==0)    
 			cout<<"0000";
		else if(p->data<10)
			cout<<"000"<<p->data;
		else if(p->data<100)
			cout<<"00"<<p->data;
		else if(p->data<1000)
			cout<<"0"<<p->data;
  		else cout<<p->data;
  		p=p->next;
		if(p==L) break;
		cout<<",";
 	}
 	cout<<endl;
}

int main(){	 
    int n1=0,n2=0;
	List A,B,C; //定义链表A,B
	Init(A);
	Init(B);
	Init(C);  //相加的结果存入C链表 
	cout << "********************************************************************" << endl;
	cout << "*                      任意长的整数加减法运算                      *" << endl;
	cout << "********************************************************************" << endl;
	cout << endl;
	cout << "操作要求:" << endl;
	cout << "1.整型变量的范围:-(2^15 -1)~(2^15 -1)" << endl;
	cout << "2.输入形式每四组一位,组间用逗号分隔开,如1986,8213,1935,2736,3299" << endl;
	cout << endl;
	cout << "请输入第一个带符号位的整数(如-2345,6789或+1234,4567):" << endl;
	//输入第一个长整数
	char sym1;
	while(1){
		cin>>sym1;
		if(sym1=='+'||sym1=='-') break;
		cout << "符号输入错误,请重输第一个整数!"<<endl;
		fflush(stdin); //清除输入 
	}
	Create(A,n1);
	cout << "请输入第二个带符号位的整数(如-2345,6789或+1234,4567):" << endl;
	//输入第二个长整数 
	char sym2;
	while(1){ 
		cin>>sym2;
		if(sym2=='+'||sym2=='-') break;
		cout << "符号输入错误,请重输第一个整数!"<<endl;
		fflush(stdin); //清除输入 
	}	
	Create(B,n2);
	cout << "选择加法请输入+,选择减法请输入-(如+):"  << endl; 
	Select(A,B,C,n1,n2,sym1,sym2);
	//计算过程
	cout << "结果为:"  << endl;
	if(finalsym=='-') cout<<finalsym;
	Show(C);
} 

评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值