任意長的整數加法運算



【問題描述】

      設計一個實現任意長的整數進行加法運算的演示程序。

【基本要求】

  1. 系統以菜單提示方式工作;

  2. 基本功能包括大整數輸入、加法運算、大整數輸出;

  3. 利用雙向循環鏈表實現長整數的存儲,每個結點含一個整型變量。任何整型變量的範圍是-(215-1)~(215-1)

  4. 輸入和輸出形式:按中國對於長整數的表示習慣,每四位一組,組間用逗號隔開。如:1,0000,0000,0000,0000

    【測試數據】

  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”。

    //設計兩個函數   一個純加法計算   另一個減法運算
    #include "stdafx.h"
    #include <iostream>
    #include <string.h>
    #include <stdlib.h>
    #include <cstdlib>
    #include <string>
    using namespace std;
    //加數和被加數的存儲結構
    struct Cltype
    {
    	int num;
    	Cltype *nextNode;
    	Cltype *preNode;
    };
    //結果的存儲結構
    struct Answer
    {
    	int num = 0;
    	int caorbo = 0;
    	Answer *nextNode;
    	Answer *preNode;
    };
    Cltype*FindEnd(Cltype*head)  //查找尾部節點
    {
    	Cltype*htemp;
    	htemp = head;
    	while (htemp->nextNode != NULL)
    	{
    		htemp = htemp->nextNode;
    	}
    	return htemp;
    }
    Answer*FindEnd(Answer*head)  //查找結果鏈表的尾部節點
    {
    	Answer*htemp;
    	htemp = head;
    	while (htemp->nextNode != NULL)
    	{
    		htemp = htemp->nextNode;
    	}
    	return htemp;
    }
    Cltype*AddnodeNum(int num, Cltype*head)  //添加節點(數據)
    {
    	Cltype *htemp, *node;
    	if (!(node = new Cltype))
    	{
    		cout << "分配內存失敗";
    		return NULL;
    	}
    	else
    	{
    		node->num = num;
    		node->nextNode = NULL;
    		if (head == NULL)
    		{
    			head = node;
    			return head;
    		}
    		htemp = head;
    		while (htemp->nextNode != NULL)
    		{
    			htemp = htemp->nextNode;
    		}
    		htemp->nextNode = node;
    		node->preNode = htemp;
    		return head;
    	}
    }
    Answer*AddnodeAns(int num, Answer*head)  //添加存儲結果的鏈表的節點
    {
    	Answer *htemp, *node;
    	if (!(node = new Answer))
    	{
    		cout << "分配內存失敗";
    		return NULL;
    	}
    	else
    	{
    		node->num = num;
    		node->nextNode = NULL;
    		if (head == NULL)
    		{
    			head = node;
    			return head;
    		}
    		htemp = head;
    		while (htemp->nextNode != NULL)
    		{
    			htemp = htemp->nextNode;
    		}
    		htemp->nextNode = node;
    		node->preNode = htemp;
    		return head;
    	}
    }
    Answer*add(Cltype*head1, Cltype*head2, Answer*head3)  //調用這個函數之前應該把各個節點的數值存放進鏈表中
    {                                                      //相加函數
    	Cltype*end1 = FindEnd(head1);
    	Cltype*end2 = FindEnd(head2);
    	Answer*End = FindEnd(head3);
    	while (end2 != head2)
    	{
    		End->num = end1->num + end2->num + End->caorbo;
    		if (End->num > 9)
    		{
    			End->num = End->num % 10;
    			End->preNode->caorbo = 1;
    		}
    		end1 = end1->preNode;
    		end2 = end2->preNode;
    		End = End->preNode;
    	}
    	End->num = head2->num + end1->num + End->caorbo;  //head2此時就是end2,從尾遍歷至頭部
    	if (End->num > 9)            //如果遍歷至頭部的話還是大於等於10 的,就進位
    	{
    		End->num = End->num % 10;
    		End->preNode->caorbo = 1;
    	}
    	while (end1 != head1)
    	{
    		end1 = end1->preNode;
    		End = End->preNode;
    		End->num = end1->num + End->caorbo;
    		if (End->num > 9)            //如果遍歷至頭部的話還是大於等於10 的,就進位
    		{
    			End->num = End->num % 10;
    			End->preNode->caorbo = 1;
    		}
    	}
    	End = End->preNode;
    	End->num = End->caorbo;
    	return head3;
    }
    //******************************************
    //減法函數  其中head1是大數鏈表的頭指針 head2是小數鏈表的頭指針
    //******************************************
    Answer*subs(Cltype*head1, Cltype*head2, Answer*head3)
    {
    	Cltype*end1 = FindEnd(head1);
    	Cltype*end2 = FindEnd(head2);
    	Answer*End = FindEnd(head3);
    	while (end2 != head2)
    	{
    		End->num = end1->num - end2->num + End->caorbo;
    		if (End->num < 0)
    		{
    			End->num += 10;
    			End->preNode->caorbo -= 1;
    		}
    		end1 = end1->preNode;
    		end2 = end2->preNode;
    		End = End->preNode;
    	}
    	End->num = end1->num - head2->num + End->caorbo;
    	if (End->num < 0)          //如果最後一次還是小於0,那麼就繼續加一個條件,讓借位等於-1
    	{
    		End->num += 10;
    		End->preNode->caorbo -= 1;
    	}
    	while (end1 != head1)
    	{
    		end1 = end1->preNode;
    		End = End->preNode;
    		End->num = end1->num + End->caorbo;
    		if (End->num < 0)          //如果最後一次還是小於0,那麼就繼續加一個條件,讓借位等於-1
    		{
    			End->num += 10;
    			End->preNode->caorbo -= 1;
    		}
    	}
    	return head3;
    }
    void AllNode(Answer*head)   //需要修改
    {
    	int a[100];
    	memset(a, 0, 100);
    	int i = 0;
    	Answer*temp, *thend;
    	thend = FindEnd(head);
    	temp = head;
    	while (temp)
    	{
    		if (temp->num == -1 || temp->num == 0)   //判斷結果是不是都是0如果是則輸出一個0
    		{
    			if (temp == thend)
    				cout << "0";
    		}
    		if (temp->num != -1 && temp->num != 0)
    			break;
    		temp = temp->nextNode;
    	}
    	Answer*htemp;
    	int flag = 0;
    	htemp = head;
    	while (htemp)
    	{
    		if (htemp->num != -1 && htemp->num != 0 || flag == 1)
    		{
    			a[i++] = htemp->num;
    			flag = 1;
    		}
    		htemp = htemp->nextNode;
    	}
    	if (i > 4)
    	{
    		int k, w = i % 4;
    		for (k = 0; k < w; k++)
    			cout << a[k];
    		if (w != 0)        //通過這個判斷語句讓對四如果爲空的後面不輸出逗號
    			cout << ",";
    		for (; k < i; k++)
    		{
    			for (int d = 0; d < 4; d++)    //四位四位一輸出
    			{
    				cout << a[k];
    				k++;
    			}
    			k--;
    			if (k != i - 1)    //作爲一個判斷標誌,讓最後一位數的後面的標點符號不輸出
    				cout << ",";
    		}
    	}
    	else
    	{
    		for (int g = 0; g < i; g++)
    			cout << a[g];
    	}
    }
    int count(string s)
    {
    	int cnt = 0;
    	for (auto c : s)
    	if (isdigit(c))
    		++cnt;
    	return cnt;
    }
    //****************************************
    //將最初的串中的字符剔除掉,並將符號存在下標爲0的位置
    //****************************************
    void send(string org, char*&num, int n)
    {
    	int k = 1;
    	if (isdigit(org[0]))
    		num[0] = '1';    //1代表正數
    	else num[0] = '0';   //0代表負數
    	for (int i = 0; k < n, i < org.length(); i++)
    	{
    		if (isdigit(org[i]))
    		{
    			num[k] = org[i];
    			k++;
    		}
    	}
    }
    //******************************************
    //return 1  num1的絕對值大於num2
    //******************************************
    int compare(string s1, string s2)
    {
    	int a = count(s1) + 1;   //除掉字符時候數字的個數+1是存儲符號
    	int b = count(s2) + 1;
    	if (a > b) return 1;
    	if (a < b) return 0;
    	char*num1 = new char[a];
    	char*num2 = new char[b];
    	memset(num1, 0, a);        //初始化存儲加數和被加數的字符型數組
    	memset(num2, 0, b);
    	send(s1, num1, a);         //調用函數將字符串中的符號去掉並將數字存在num1 num2中
    	send(s2, num2, b);
    	for (int i = 1; i < a; i++)
    	{
    		if (num1[i]>num2[i])
    			return 1;
    		if (num1[i] < num2[i])
    			return 0;
    	}
    	return 1;
    }
    Cltype*ass(Cltype*head, char*num, int n)
    {
    	for (int i = 1; i <= n - 1; i++)
    	{
    		int su = num[i] - '0';
    		head = AddnodeNum(su, head);
    	}
    	return head;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
    	Cltype*head1 = NULL, *head2 = NULL;/***************我們要讓Num1是大數*/
    	Answer*head3 = NULL;
    	//	int length1, length2;
    	string s1, s2;
    	cin >> s1 >> s2;
    	int a = count(s1) + 1;   //除掉字符時候數字的個數+1是存儲符號
    	int b = count(s2) + 1;
    	char*num1 = new char[a];
    	char*num2 = new char[b];
    	memset(num1, 0, a);        //初始化存儲加數和被加數的字符型數組
    	memset(num2, 0, b);
    	send(s1, num1, a);         //調用函數將字符串中的符號去掉
    	send(s2, num2, b);
    	head1 = ass(head1, num1, a);  //傳入鏈表
    	head2 = ass(head2, num2, b);
    	int q = a > b ? a + 1 : b + 1;
    	for (int j = 1; j < q; j++)
    		head3 = AddnodeAns(-1, head3);
    	if (compare(s1, s2))
    	{
    		if (num1[0] == '0' && num2[0] == '0')
    		{
    			add(head1, head2, head3);
    			cout << "-";
    			AllNode(head3);
    		}
    		if (num1[0] == '1' && num2[0] == '0')
    		{
    			subs(head1, head2, head3);
    			AllNode(head3);
    		}
    		if (num1[0] == '0'&& num2[0] == '1')
    		{
    			subs(head1, head2, head3);
    			cout << "-";
    			AllNode(head3);
    		}
    		if (num1[0] == '1' && num2[0] == '1')
    		{
    			add(head1, head2, head3);
    			AllNode(head3);
    		}
    	}
    	else
    	{
    		if (num1[0] == '0' && num2[0] == '0')
    		{
    			add(head2, head1, head3);
    			cout << "-";
    			AllNode(head3);
    		}
    		if (num1[0] == '1' && num2[0] == '0')
    		{
    			subs(head2, head1, head3);
    			cout << "-";
    			AllNode(head3);
    		}
    		if (num1[0] == '0' && num2[0] == '1')
    		{
    			subs(head2, head1, head3);
    			AllNode(head3);
    		}
    		if (num1[0] == '1' && num2[0] == '1')
    		{
    			add(head2, head1, head3);
    			AllNode(head3);
    		}
    	}
    	return 0;
    }
    

發佈了10 篇原創文章 · 獲贊 11 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章