【問題描述】
設計一個實現任意長的整數進行加法運算的演示程序。
【基本要求】
-
系統以菜單提示方式工作;
-
基本功能包括大整數輸入、加法運算、大整數輸出;
-
利用雙向循環鏈表實現長整數的存儲,每個結點含一個整型變量。任何整型變量的範圍是-(215-1)~(215-1);
-
輸入和輸出形式:按中國對於長整數的表示習慣,每四位一組,組間用逗號隔開。如:1,0000,0000,0000,0000
【測試數據】
-
0;0;應輸入“0”。
-
-2345,6789;-7654,3211;應輸出“-1,0000,0000”。
-
-9999,9999;1,0000,0000,0000;應輸出“9999,0000,0001”。
-
1,0001,0001;-1,0001,0001;應輸出“0”。
-
1,0001,0001;-1,0001,0000;應輸出“1”。
-
-9999,9999,9999;-9999,9999,9999;應輸出“-1,9999,9999,9998”。
-
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; }