鱼C论坛

 找回密码
 立即注册
查看: 3163|回复: 1

[技术交流] 关于超大数相加的一个算法

[复制链接]
发表于 2016-1-22 11:19:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 麦田管理中心 于 2016-1-22 11:30 编辑

/*这是两个超大数相加的算法,思路就是个位相加取余保存在一个结果栈中,然后个位相加的结果÷10结果赋值给carry,然后十位相加再加carry取余放到结果栈里,同理依次算下去,<u>如果需要全部源码请说一下,我马上贴出来(主要是想解决问题)*/


  1. stack<int> addinglargenumber(stack<int> stack1,stack<int> stack2)
  2. /*最高位放在栈的最下面,如果这两个形参被赋值为相同的实参,那么stack1和stack2共用一段内存,这个导致两个相同的数相加出错*/
  3. {
  4.         int carry = 0;
  5.         stack<int> stacktmp = stack2;
  6. /*stacktmp {head=0x00f6d448 {vacabulary=9 next=0x00f6d410 {vacabulary=8 next=0x00f6d3d8 {vacabulary=7 next=0x00f6d3a0 {...} ...} ...} ...} ...}*/
  7. /*stack1 {head=0x00f6d448{vacabulary=9 next=0x00f6d410 {vacabulary=8 next=0x00f6d3d8 {vacabulary=7 next=0x00f6d3a0 {...} ...} ...} ...} ...}*/
  8. //比较stack1和stacktmp的地址始终相同,导致pop()函数运算出错
  9.         stack<int> stack3;//存放大数的和
  10.         int a = 0, b = 0;
  11.         while (!stack1.isempty() && !stacktmp.isempty())
  12.         {
  13.                 a = stack1.topEI(); b = stacktmp.topEI();
  14.                 stack3.push((stack1.pop() + stacktmp.pop()/*问题可能出现在这*/ + carry) % 10);
  15.         /*掉用pop()函数是因为共用内存所以出错*/               
  16.                 carry = (a + b + carry) / 10;
  17.         }
  18.         if (stack1.isempty() && stacktmp.isempty())
  19.         {
  20.                 if (carry != 0)
  21.                 {
  22.                         stack3.push(carry);
  23.                 }
  24.         }
  25.         else
  26.         {
  27.                 if (stack1.isempty())
  28.                         while (!stacktmp.isempty())
  29.                         {
  30.                                 stack3.push((a = (stacktmp.pop() + carry)) % 10);
  31.                                 carry = a / 10;
  32.                         }
  33.                 else
  34.                 {
  35.                         while (!stack1.isempty())
  36.                         {
  37.                                 stack3.push((a = (stack1.pop() + carry)) % 10);
  38.                                 carry = a / 10;
  39.                         }
  40.                 }
  41.         }
  42.         return stack3;
  43. }
  44. template<class T>
  45. T stack<T>::pop()
  46. {
  47. node<T> *tmp = head;
  48. T a = head->vacabulary;//a的赋值有问题
  49. head = head->next;//无法读取内存
  50. delete tmp;
  51. return a;
  52. }

  53. void main()
  54. {
  55. stack<int> s1, s2, s3;
  56. for (int i = 0; i < 10; i++)
  57.   s1.push(i);
  58. s1.print();
  59. s2 = s1;
  60. s2.print();
  61. s3 = addinglargenumber(s1, s1);
  62. s3.print();
  63. }
复制代码


小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-1-22 20:11:41 | 显示全部楼层
问题我自己已经解决,有兴趣的同学可以运行一下

  1. #include<iostream>
  2. using namespace std;
  3. template<class T>
  4. class node
  5. {
  6. public:
  7.         node(T a, node* b = 0, node* c = 0)
  8.         {
  9.                 vacabulary = a;
  10.                 next = b;
  11.                 pre = c;
  12.         }
  13.         T vacabulary;
  14.         node *next, *pre;
  15. };
  16. template<class T>
  17. class stack
  18. {
  19. public:
  20.         node<T> *head, *tail;
  21.         stack()
  22.         {
  23.                 head = 0; tail = 0;
  24.         }
  25.         void push(T a);//将字符放在栈的顶部
  26.         void clear();//清空栈
  27.         int isempty();//判断栈是否为空,空就返回0
  28.         T pop();//弹出顶部的元素
  29.         T topEI();//获取顶部的元素,但不删除
  30.         void operator=(stack);//重载=运算符
  31.         void upsidedown();//颠倒栈的顺序
  32.         void print()
  33.         {
  34.                 for (node<T>* tmp = head; tmp != NULL; tmp = tmp->next)
  35.                 {
  36.                         if (tmp->vacabulary > 9)
  37.                                 cout << char(tmp->vacabulary + 55);
  38.                         else
  39.                                 cout << tmp->vacabulary;
  40.                 }
  41.                 cout << endl;
  42.         }
  43. };
  44. template<class T>
  45. void stack<T>::push(T a)
  46. {
  47.         node<T> *tmp;
  48.         if (head == NULL)
  49.         {
  50.                 head = new node<T>(a, 0, 0);
  51.                 tail = head;
  52.         }
  53.         else
  54.         {
  55.                 if (head == tail)
  56.                 {
  57.                         tmp = new node<T>(a, head, 0);
  58.                         head->pre = tmp;
  59.                         head = tmp;
  60.                 }
  61.                 else
  62.                 {
  63.                         tmp = new node<T>(a, head, 0);
  64.                         head->pre = tmp;
  65.                         head = tmp;
  66.                 }
  67.         }
  68. }
  69. template<class T>
  70. void stack<T>::clear()
  71. {
  72.         node<T> *tmp = head;
  73.         if (head == NULL)
  74.         {
  75.                 cout << "清空完成" << endl;
  76.         }
  77.         else
  78.         {
  79.                 if (head == tail)
  80.                 {
  81.                         delete head;
  82.                         cout << "清空完成" << endl;
  83.                 }
  84.                 else
  85.                 {
  86.                         for (; head != NULL; head = tmp)
  87.                         {
  88.                                 tmp = tmp->next;
  89.                                 delete head;
  90.                         }
  91.                         cout << "清空完成" << endl;
  92.                 }
  93.         }
  94. }
  95. template<class T>
  96. int stack<T>::isempty()
  97. {
  98.         if (head == NULL)
  99.                 return 1;
  100.         return 0;
  101. }
  102. template<class T>
  103. T stack<T>::pop()
  104. {
  105.         node<T> *tmp = head;
  106.         T a = head->vacabulary;
  107.         head = head->next;
  108.         delete tmp;
  109.         return a;
  110. }
  111. template<class T>
  112. T stack<T>::topEI()
  113. {
  114.         return head->vacabulary;
  115. }

  116. template<class T>
  117. void stack<T>::operator=(stack<T> a)
  118. {
  119.         node<T> *n;
  120.         n = a.tail;
  121.         this->clear();
  122.         while (n != NULL)
  123.         {
  124.                 this->push(n->vacabulary);
  125.                 n = n->pre;
  126.         }
  127. }
  128. template<class T>
  129. void stack<T>::upsidedown()
  130. {
  131.         stack<T> stack1;
  132.         stack1.operator=(*this);
  133.         this->clear();
  134.         while (!stack1.isempty())
  135.         {
  136.                 this->push(stack1.pop());
  137.         }
  138.         stack1.clear();
  139. }
  140. /*这是两个超大数相加的算法,思路就是个位相加取余保存在一个结果栈中,然后个位相加的结果÷10结果赋值给carry,然后十位相加再加carry取余放到结果栈里,同理依次算下去*/
  141. stack<int> addinglargenumber(stack<int> stack1,stack<int> stack2)
  142. {
  143.         int carry = 0;
  144.         stack<int> stacktmp1;
  145.         stack<int> stacktmp2;
  146.         stacktmp1.operator=(stack1);
  147.         stacktmp2.operator=(stack2);//这样的赋值就成功了,如果直接写=好而不调用重载运算符,那就是stacktmp和stack2公用一段内存
  148.         stack<int> stack3;//存放大数的和
  149.         int a = 0, b = 0;
  150.         while (!stacktmp1.isempty() && !stacktmp2.isempty())
  151.         {
  152.                 a = stacktmp1.topEI(); b = stacktmp2.topEI();
  153.                 stack3.push((stacktmp1.pop() + stacktmp2.pop() + carry) % 10);
  154.                 carry = (a + b + carry) / 10;
  155.         }
  156.         if (stacktmp1.isempty() && stacktmp2.isempty())
  157.         {
  158.                 if (carry != 0)
  159.                 {
  160.                         stack3.push(carry);
  161.                 }
  162.         }
  163.         else
  164.         {
  165.                 if (stacktmp1.isempty())
  166.                         while (!stacktmp2.isempty())
  167.                         {
  168.                                 stack3.push((a = (stacktmp2.pop() + carry)) % 10);
  169.                                 carry = a / 10;
  170.                         }
  171.                 else
  172.                 {
  173.                         while (!stacktmp1.isempty())
  174.                         {
  175.                                 stack3.push((a = (stacktmp1.pop() + carry)) % 10);
  176.                                 carry = a / 10;
  177.                         }
  178.                 }
  179.         }
  180.         return stack3;//个位放在结果栈的最下面
  181. }

  182. void multiplelargenumber()//两个超大数相乘
  183. {
  184.         int i = 0;
  185.         int carry = 0;
  186.         stack<int> stack1;//两个因子
  187.         stack<int> stack2;
  188.         stack<int> stack3;//存放结果
  189.         stack<int> stack4;//临时存放stack1
  190.         char tmp[1000];//临时储存用的
  191.         cout << "输入第1个数字(e代表结束)" << endl;
  192.         for (i = 0; 1; i++)
  193.         {
  194.                 cin >> tmp[i];
  195.                 if (tmp[i] == 'e')
  196.                         break;
  197.         }
  198.         i = 0;
  199.         while (tmp[i] != 'e')
  200.         {
  201.                 stack1.push((int)tmp[i++] - 48);//最高位放在栈的最下面
  202.         }

  203.         cout << "输入第2个数字(e代表结束)" << endl;
  204.         for (i = 0; 1; i++)
  205.         {
  206.                 cin >> tmp[i];
  207.                 if (tmp[i] == 'e')
  208.                         break;
  209.         }
  210.         i = 0;
  211.         while (tmp[i] != 'e')
  212.         {
  213.                 stack2.push((int)tmp[i++] - 48);//-48很重要,‘1’和1不一样。。//最高位放在栈的最下面
  214.         }
  215.         /**********以上为创建两个因子的栈************/
  216.         stack4 = stack1;
  217.         cout << "栈的个数" << i << endl;
  218.         int stacknum = i;
  219.         stack<int> *tmpp = new stack<int>[i];//创建的一系列栈用来求和,一共有i个栈
  220.         int a, b;
  221.         int j = 0;
  222.         i = 0;
  223.         for (; !stack2.isempty();)//用于计算求和栈,个位放在最下面
  224.         {
  225.                 for (; !stack1.isempty();)
  226.                 {
  227.                         tmpp[i].push(((a = stack2.topEI())*(b = stack1.pop()) + carry) % 10);
  228.                         carry = (((a*b) + carry) / 10);
  229.                 }
  230.                 stack2.pop();
  231.                 stack1 = stack4;
  232.                 i++;
  233.                 if (i != stacknum)
  234.                 {
  235.                         for (j = 0; j < i; j++)
  236.                                 tmpp[i].push(0);
  237.                 }
  238.         }
  239.         for (j = 0; j < stacknum; j++)//所有的求和栈颠倒顺序,用于最后一步求得积
  240.         {
  241.                 tmpp[j].upsidedown();
  242.                 tmpp[j].print();
  243.         }
  244.         stack3.operator=(tmpp[0]);
  245.         stack<int> stacktmp;
  246.         for (j = 1; j < stacknum; j++)
  247.         {
  248.                 stacktmp.operator=(addinglargenumber(stack3, tmpp[j]));
  249.                 stack3.clear();
  250.                 stack3.operator=(stacktmp);
  251.                 stacktmp.clear();
  252.                 stack3.upsidedown();
  253.         }
  254.         stack3.upsidedown();
  255.         stack3.print();
  256. }
  257. void main()
  258. {
  259.         multiplelargenumber();
  260. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-21 20:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表