鱼C论坛

 找回密码
 立即注册
查看: 1891|回复: 5

[已解决]C++链表实现的一个大数运算问题!

[复制链接]
发表于 2019-4-23 15:04:31 | 显示全部楼层 |阅读模式

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

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

x
其实已经发过一个帖子了- =不过又出现了一些新的问题,基本思路就是用节点存储一个无符号的32位整形,然后串成链表来表示大数,这个程序再跑到第24轮的时候会出一个看不懂的异常(terminate called after throwing an instance of 'St9bad_alloc' what():  std::bad_alloc)- =然后终止
问题基本已经锁定在remove_zero_end()函数里,因为不调用它就可以正常运行- =不过会浪费大量的内存,这是一个递归的删除函数,用来从表尾开始删除值为0的节点。真的是搞不懂为什么啊,求大神指点。
remove_zero_end代码:
  1. void hugeNumber::remove_zero_end()
  2. {

  3.     if(this->hgHead == nullptr)
  4.         return;
  5.     remove_zero_end(hgHead);


  6. }

  7. void hugeNumber::remove_zero_end(hgNumNode* parent)
  8. {
  9.     hgNumNode* nextNode = parent->next;
  10.     if(nextNode == nullptr)
  11.         return;
  12.     else if(nextNode->next != nullptr)
  13.         remove_zero_end(nextNode);
  14.     if(nextNode->value32 == 0)
  15.     {
  16.         delete nextNode;
  17.         parent->next = nullptr;
  18.         this->length--;
  19.     }


  20. }
复制代码


全部代码如下:
  1. #include <iostream>
  2. #include <conio.h>
  3. #include "hugeNumber.h"
  4. #include <cstdlib>
  5. using namespace std;

  6. int main()
  7. {

  8.    hugeNumber h1;
  9.    hugeNumber h2;
  10.    h1.reset_self(1);
  11.    h2.reset_self(1);




  12.    for(int i = 0;i < 1000;i++)
  13.    {
  14.        h1 += &h2;
  15.        h2 += &h1;
  16.        //h2 += &h1;
  17.        cout<<"h1.length:"<<h1.length<<"  h2.length:"<<h2.length<<endl;
  18.        cout<<"h1."<<i+1<<"."<<h1.Tostring()<<"  "<<"h2."<<i+2<<"."<<h2.Tostring()<<endl;
  19.        system("pause");

  20.    }


  21.     /*
  22.     unsigned int nFibonacci[1000];
  23.     nFibonacci[0] = 1;
  24.     nFibonacci[1] = 1;
  25.     cout<<"1."<<nFibonacci[0]<<endl;
  26.     cout<<"2."<<nFibonacci[1]<<endl;
  27.     for(int i = 2;i < 1000;i++)
  28.     {
  29.         nFibonacci[i] = nFibonacci[i-1]+nFibonacci[i-2];
  30.         cout<<i+1<<"."<<nFibonacci[i]<<endl;
  31.         getch();
  32.     }
  33.     */
  34.     return 0;
  35. }
复制代码


类定义:
  1. #ifndef HUGENUMBER_H
  2. #define HUGENUMBER_H
  3. #define max_num 0xffffffff
  4. #include <iostream>
  5. using namespace std;
  6. class hgNumNode
  7. {
  8.    public:
  9.      unsigned int value32;//存储32位无符号整形
  10.      hgNumNode* next;//链表指针
  11.      hgNumNode(unsigned int values){this->value32 = values;this->next=nullptr;}
  12.      virtual ~hgNumNode(){};//尽量给缺省实现的虚函数加上函数体否则可能会出现undefined reference to `vtable for
  13. };

  14. class hugeNumber
  15. {
  16.     public:
  17.         hugeNumber();
  18.         virtual ~hugeNumber();
  19.         hgNumNode* hgHead;//链表头节点
  20.         int length;//链表长度
  21.         bool add_Node_in_list(unsigned int values);//添加一个新节点到链表中
  22.         void cleanList();//清空链表
  23.         void reset_self(unsigned int values);//清空链表并重设第一个节点的值
  24.         void remove_zero_end();//删除值为0的节点
  25.         void remove_zero_end(hgNumNode* parent);
  26.         void operator +=(hugeNumber* afterNum);//重载+=
  27.         string Tostring();
  28.         string Tostring(hgNumNode* heads);

  29.     protected:

  30.     private:
  31. };

  32. #endif // HUGENUMBER_H
复制代码


类的实现:
  1. #include "hugeNumber.h"
  2. #include <cstdio>
  3. #include <cstdlib>

  4. hugeNumber::hugeNumber()
  5. {
  6.     this->hgHead = nullptr;
  7.     this->length = 0;
  8. }

  9. hugeNumber::~hugeNumber()
  10. {
  11.     cleanList();
  12. }

  13. bool hugeNumber::add_Node_in_list(unsigned int values)
  14. {
  15.     hgNumNode* addNode = new hgNumNode(values);
  16.     hgNumNode* findNode =this->hgHead;
  17.     addNode->next = nullptr;
  18.     if(this->length == 0)
  19.     {
  20.         this->hgHead =addNode;
  21.         this->length= 1;
  22.         return true;
  23.     }
  24.     while(findNode->next != nullptr)findNode = findNode->next;
  25.     findNode->next = addNode;

  26.     this->length++;
  27.     return true;
  28. }

  29. void hugeNumber::cleanList()
  30. {
  31.     hgNumNode* delNode = this->hgHead;
  32.     hgNumNode* nextNode = nullptr;
  33.     while(delNode != nullptr)//不能再对象析构中调用delete删除相同对象,这样会导致无限调用析构的死循环递归
  34.     {
  35.          nextNode = delNode->next;
  36.          delete delNode;
  37.          delNode = nextNode;
  38.     }
  39.     this->length = 0;
  40.     this->hgHead = nullptr;


  41. }

  42. void hugeNumber::reset_self(unsigned int tar)
  43. {
  44.     cleanList();
  45.     hgNumNode* newNode= new hgNumNode(tar);
  46.     this->hgHead = newNode;
  47.     this->hgHead->next= nullptr;
  48.     this->length++;
  49. }
  50. void hugeNumber::remove_zero_end()
  51. {

  52.     if(this->hgHead == nullptr)
  53.         return;
  54.     remove_zero_end(hgHead);


  55. }

  56. void hugeNumber::remove_zero_end(hgNumNode* parent)
  57. {
  58.     hgNumNode* nextNode = parent->next;
  59.     if(nextNode == nullptr)
  60.         return;
  61.     else if(nextNode->next != nullptr)
  62.         remove_zero_end(nextNode);
  63.     if(nextNode->value32 == 0)
  64.     {
  65.         delete nextNode;
  66.         parent->next = nullptr;
  67.         this->length--;
  68.     }


  69. }

  70. void hugeNumber::operator+=(hugeNumber* afterNum)
  71. {
  72.        if(this->length < afterNum->length)
  73.         {
  74.             for(int i = this->length;i < afterNum->length;i++)
  75.                 this->add_Node_in_list(0);

  76.         }
  77.        this->add_Node_in_list(0);
  78.     //this->add_Node_in_list(0);

  79.     hgNumNode* h1 = this->hgHead;
  80.     hgNumNode* h2 = afterNum->hgHead;

  81.     while(true)
  82.     {
  83.         if(h1 == nullptr)
  84.             break;
  85.         if(h2 == nullptr)
  86.             break;
  87.         if(max_num - h1->value32 < h2->value32)
  88.             h1->next->value32+=1;
  89.         h1->value32 += h2->value32;
  90.         h1 = h1->next;
  91.         h2 = h2->next;
  92.         remove_zero_end();
  93.         //cout<<this->Tostring()<<endl;

  94.     }

  95. }

  96. string hugeNumber::Tostring()
  97. {
  98.     if(this->hgHead == nullptr)
  99.         return "0";

  100.     string ret = "0x"+Tostring(this->hgHead);
  101.     return ret;
  102. }

  103. string hugeNumber::Tostring(hgNumNode* heads)
  104. {
  105.     string ret ="-";
  106.     if(heads->next != nullptr)
  107.     {
  108.         ret+=Tostring(heads->next);
  109.     }
  110.     char temp[10];
  111.     sprintf(temp,"%08x",heads->value32);
  112.     ret.append(temp);
  113.     return ret;
  114. }
复制代码
最佳答案
2019-4-23 20:12:40
不好意思,我没看清。。。
  1. void hugeNumber::operator+=(hugeNumber* afterNum)
  2. {
  3.        if(this->length < afterNum->length)
  4.         {
  5.             for(int i = this->length;i < afterNum->length;i++)
  6.                 this->add_Node_in_list(0);

  7.         }
  8.        this->add_Node_in_list(0);
  9.     //this->add_Node_in_list(0);

  10.     hgNumNode* h1 = this->hgHead;
  11.     hgNumNode* h2 = afterNum->hgHead;

  12.     while(true)
  13.     {
  14.         if(h1 == nullptr)
  15.             break;
  16.         if(h2 == nullptr)
  17.             break;
  18.         if(max_num - h1->value32 < h2->value32)
  19.             h1->next->value32+=1;
  20.         h1->value32 += h2->value32;
  21.         h1 = h1->next;
  22.         h2 = h2->next;
  23.         remove_zero_end();
  24.         //cout<<this->Tostring()<<endl;

  25.     }

  26. }
复制代码

把remove_zero_end丢出来
  1. void hugeNumber::operator+=(hugeNumber* afterNum)
  2. {
  3.        if(this->length < afterNum->length)
  4.         {
  5.             for(int i = this->length;i < afterNum->length;i++)
  6.                 this->add_Node_in_list(0);

  7.         }
  8.        this->add_Node_in_list(0);
  9.     //this->add_Node_in_list(0);

  10.     hgNumNode* h1 = this->hgHead;
  11.     hgNumNode* h2 = afterNum->hgHead;

  12.     while(true)
  13.     {
  14.         if(h1 == nullptr)
  15.             break;
  16.         if(h2 == nullptr)
  17.             break;
  18.         if(max_num - h1->value32 < h2->value32)
  19.             h1->next->value32+=1;
  20.         h1->value32 += h2->value32;
  21.         h1 = h1->next;
  22.         h2 = h2->next;

  23.         //cout<<this->Tostring()<<endl;

  24.     }
  25.     remove_zero_end();
  26. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2019-4-23 19:12:07 | 显示全部楼层
所以我的解答你是根本没看么。。问题都给你指出来改好了
。。结果你又改回去又重新来提。。。看不懂
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-4-23 19:46:09 | 显示全部楼层
Croper 发表于 2019-4-23 19:12
所以我的解答你是根本没看么。。问题都给你指出来改好了
。。结果你又改回去又重新来提。。。看不懂

没有啊大佬,你说那几点我都改了,顺便还把那个基本没啥用尾节点指针给去掉了啊。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-4-23 19:48:21 | 显示全部楼层
°希作先生丶 发表于 2019-4-23 19:46
没有啊大佬,你说那几点我都改了,顺便还把那个基本没啥用尾节点指针给去掉了啊。。

删除的时候重新建了个中间的交换节点,然后直接把尾节点给去掉了,因为我感觉再递归里不好确认它到底该指哪。真的没有无视你的意思啊
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-4-23 20:12:40 | 显示全部楼层    本楼为最佳答案   
不好意思,我没看清。。。
  1. void hugeNumber::operator+=(hugeNumber* afterNum)
  2. {
  3.        if(this->length < afterNum->length)
  4.         {
  5.             for(int i = this->length;i < afterNum->length;i++)
  6.                 this->add_Node_in_list(0);

  7.         }
  8.        this->add_Node_in_list(0);
  9.     //this->add_Node_in_list(0);

  10.     hgNumNode* h1 = this->hgHead;
  11.     hgNumNode* h2 = afterNum->hgHead;

  12.     while(true)
  13.     {
  14.         if(h1 == nullptr)
  15.             break;
  16.         if(h2 == nullptr)
  17.             break;
  18.         if(max_num - h1->value32 < h2->value32)
  19.             h1->next->value32+=1;
  20.         h1->value32 += h2->value32;
  21.         h1 = h1->next;
  22.         h2 = h2->next;
  23.         remove_zero_end();
  24.         //cout<<this->Tostring()<<endl;

  25.     }

  26. }
复制代码

把remove_zero_end丢出来
  1. void hugeNumber::operator+=(hugeNumber* afterNum)
  2. {
  3.        if(this->length < afterNum->length)
  4.         {
  5.             for(int i = this->length;i < afterNum->length;i++)
  6.                 this->add_Node_in_list(0);

  7.         }
  8.        this->add_Node_in_list(0);
  9.     //this->add_Node_in_list(0);

  10.     hgNumNode* h1 = this->hgHead;
  11.     hgNumNode* h2 = afterNum->hgHead;

  12.     while(true)
  13.     {
  14.         if(h1 == nullptr)
  15.             break;
  16.         if(h2 == nullptr)
  17.             break;
  18.         if(max_num - h1->value32 < h2->value32)
  19.             h1->next->value32+=1;
  20.         h1->value32 += h2->value32;
  21.         h1 = h1->next;
  22.         h2 = h2->next;

  23.         //cout<<this->Tostring()<<endl;

  24.     }
  25.     remove_zero_end();
  26. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2019-4-23 20:19:16 | 显示全部楼层
Croper 发表于 2019-4-23 20:12
不好意思,我没看清。。。

把remove_zero_end丢出来

哦!成功了,感谢大佬无私的帮助~
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-7 23:33

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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