【问题描述】
设计一个实现任意长的整数进行加法运算的演示程序。
【基本要求】
-
系统以菜单提示方式工作;
-
基本功能包括大整数输入、加法运算、大整数输出;
-
利用双向循环链表实现长整数的存储,每个结点含一个整型变量。任何整型变量的范围是-(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; }