Arbitrary Length Integer Addition and Subtraction Operations

Posted by countrygyrl on Mon, 23 Sep 2019 07:22:48 +0200

Topic Requirements: Design an algorithm to realize an arbitrary length of integers for addition and subtraction operations of the demonstration program. For example, the addition results of 1234, 5123, 4512, 3451, 2345 and - 1111, 1111, 1111, 1111, 1111 and 1111 are 0123, 4012, 3401, 2340, 1234. The basic requirements are as follows:
(1) Using linked list to store long integers, each node contains an integer variable;
(2) The range of integer variables: -(2 ^ 15 - 1) ~ (2 ^ 15 - 1);
(3) The input and output forms are set in groups of four bits, separated by commas. For example: 1986, 8213, 1935, 2736, 3299;
The interface is friendly, each step gives appropriate operation hints, and the system has a certain fault-tolerant ability.

Demand analysis:

  1. In long integer operations, the input of long integers contains positive and negative symbols separated by four-bit commas. In the storage process, the input defines a char type to store symbols and ignores commas, which are not stored in the nodes of the linked list.
  2. Because the linked list needs to be judged and processed many times, a bidirectional circular linked list is used to store long integers, which is convenient for subsequent operations.
  3. The data addition and subtraction of each node in the list are carried out in unsigned form.
  4. Symbol addition and subtraction judgment uses another judgment method to make positive and negative symbols addition and subtraction judgment.
  5. The positive and negative sign of the output results are not carried out in the linked list. Data output is carried out by traversing the linked list while judging.
  6. Running environment: dev c++.
#include<iostream>
#include<stdlib.h>
using namespace std;

char finalsym;

typedef struct ListNode{		//Structure, bidirectional circular list 
	int data;
	struct ListNode *pre;
	struct ListNode *next;
}Node,*List;
 
void Init(List &L){		//Initialization of Bidirectional Loop List 

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

void Create(List &L, int &n){		//Establishment of a bidirectional loop list, returning the node number n, leaving the following ratio absolute value 
	int x;
	char d;
	List p=L;
	cin>>x;
	while((d=getchar())!='\n'){  //Cycle input value, encounter return end. 
		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;  //The x value input before return is stored in the node of the list. 
		n++;
		q->data=x;
		q->pre=p;
		q->next=L;
		p->next=q;
		L->pre=q;
		p=q;
}

void ListInsertT(List &L, int e){ //Head insertion value 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){ //Tail insertion value 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){   //Comparing the absolute value of two numbers, returning 1 represents L1 > L2, returning - 1 represents L1 < L2, returning 0 represents 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){    //subtraction 
	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 are equal in length 
		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 is longer than 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 is longer than 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){	//addition 
	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 are equal in length 
		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 is longer than 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 is longer than 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){  //Operational Method Judgment and Selection 
	char symbol;
	cin>>symbol;
	int num=Compare(A,B,n1,n2);
	if(symbol=='+'){
		if(sym1=='+'&&sym2=='+'){
			//a+b algorithm 
			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) algorithm 
			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) algorithm 
			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<<"Input error, please re-enter:"<<endl; 
		Select(A,B,C,n1,n2,sym1,sym2);
	}
}

void Show(List &L){ //Output result 
	Node *p;
 	if(NULL == L) return;
 	p=L->next;
 	while(p->data==0&&p->next!=L){  //The result is that the node with zero data skips the output directly until it has a numerical value or a tail node. 
 		p=p->next;
	 }
	 if(p->data==0&&p->next==L) {  //If all the data in the result list is zero 
	 	cout<<"0";
	 	return;
	 }
	 cout<<p->data;  //The first number is output directly without adding 0. 
	 p=p->next;
	 if(p==L) return;  //If P points to the last number at this time, p - > next is null, ending the output. 
	 else cout<<",";
 	while (1){       //The loop outputs the contents of the remaining nodes. 
 		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; //Define list A,B
	Init(A);
	Init(B);
	Init(C);  //Additional results are stored in the C-linked list 
	cout << "********************************************************************" << endl;
	cout << "*                      Arbitrary Length Integer Addition and Subtraction Operations                      *" << endl;
	cout << "********************************************************************" << endl;
	cout << endl;
	cout << "Operational requirements:" << endl;
	cout << "1.Scope of integer variables:-(2^15 -1)~(2^15 -1)" << endl;
	cout << "2.The input form is one in four groups separated by commas, as in 1986.,8213,1935,2736,3299" << endl;
	cout << endl;
	cout << "Please enter the first signed integer(as-2345,6789 or+1234,4567): " << endl;
	//Enter the first long integer
	char sym1;
	while(1){
		cin>>sym1;
		if(sym1=='+'||sym1=='-') break;
		cout << "Symbol input error,Please retry the first integer!"<<endl;
		fflush(stdin); //Clear input 
	}
	Create(A,n1);
	cout << "Enter the second signed integer(as-2345,6789 or+1234,4567): " << endl;
	//Enter the second long integer 
	char sym2;
	while(1){ 
		cin>>sym2;
		if(sym2=='+'||sym2=='-') break;
		cout << "Symbol input error,Please retry the first integer!"<<endl;
		fflush(stdin); //Clear input 
	}	
	Create(B,n2);
	cout << "Select Addition, please enter+,Select subtraction. Enter-(as+): "  << endl; 
	Select(A,B,C,n1,n2,sym1,sym2);
	//Computation process
	cout << "The result is:"  << endl;
	if(finalsym=='-') cout<<finalsym;
	Show(C);
}