双链表实现大整数的加法与乘法[VC++]

由于最近的实验课老师要求完成大整数的加法与乘法,所以我在网上看到了许多大整数的例子,大部分都是用汇编来完成的.当然这满足不了我们实验的要求.所以前天晚上冥思苦想到午夜12点终于找到了解决之道.当然,还是比较肤浅的,VC++高手可以略过阅读此文.

设计的思想主要是通过双链表来实现的.利用双链表的节点存储每位的数字,利用前驱进行对上一个位数的使用.用后继来连接后面的节点.通过对"+"号和"*"号的重载实现对大整数的加和乘.理论上可以实现N多位的运算,只要你的机器内存够大...程序的重点在于运算符的重载.

本程序主要由三个文件构成:

BigInteger.h 包涵了对节点的结构定义,以及类BigInteger的定义.

BigInteger.cpp 包涵了BigInteger类里面成员函数的具体内容.

main.cpp 主函数...

 

//BigInteger.h

struct Node        //定义了节点的结构
{
 char Num;
 Node *Prev,*Next;
};

class BigInteger      //定义BigInteger 类
{
 Node *Head,*End,*TempNode;
 void AddHead(char Num);
 void AddEnd(char Num);
 public:
  BigInteger();
  BigInteger(const BigInteger &BigNum);
  void GetNumber();
  void disp();
  BigInteger operator + (const BigInteger &BigNum);
  BigInteger operator * (const BigInteger &BigNum);
  BigInteger operator = (const BigInteger &BigNum);
  ~BigInteger();
};

 

//BigInteger.cpp

#include <iostream.h>
#include <stdio.h>
#include "BigInteger.h"

BigInteger::BigInteger()        //构造函数,将每个节点置空.
{
 Head=End=TempNode=NULL;
}

BigInteger::BigInteger(const BigInteger &BigNum)     //拷贝构造
{
 Node *p;
 Head=End=TempNode=NULL;
 p=BigNum.Head;
 while(p)
 {
  AddEnd(p->Num);
  p=p->Next;
 }
}

BigInteger::~BigInteger()        //析构
{
 Node *NextNode;
 if(Head==NULL)
  return;
 TempNode=Head;
 while(TempNode)
 {
  NextNode=TempNode->Next;
  delete TempNode;
  TempNode=NextNode;
 }
 Head=NULL;
 End=NULL;
 TempNode=NULL;
}

void BigInteger::AddHead(char Num)        //在链表头插入节点的操作
{
 TempNode=new Node;
 TempNode->Num=Num;
 TempNode->Prev=NULL;
 if(!Head)
 {
  Head=End=TempNode;
  TempNode->Next=NULL;
 }
 else
 {
  TempNode->Next=Head;
  Head->Prev=TempNode;
  Head=TempNode;
 }
}

void BigInteger::AddEnd(char Num)       //在链表尾插入节点的操作
{
 TempNode=new Node;
 TempNode->Num=Num;
 TempNode->Next=NULL;
 if(!Head)
 {
  Head=End=TempNode;
  TempNode->Prev=NULL;
 }
 else
 {
  TempNode->Prev=End;
  End->Next=TempNode;
  End=TempNode;
 }
}

void BigInteger::GetNumber()            //输入部分
{
 char key;
 int count=0,num=0;
 while((key=getchar())!=10)            //判断输入的是否是回车,不是的话将内容从后到前放到链表中.
 {
  if(key>='0' && key<='9')
  {
   num=key-'0';
   AddEnd(num);
   num=0;
  }
 }
}

BigInteger BigInteger::operator + (const BigInteger &BigNum2)    //重载"+"
{
 BigInteger &BigNum1=*this,result;
 Node *temp1,*temp2;
 int TempNum,rest=0;
 temp1=BigNum1.End;            //将临时链表首地址放置到输入链表的尾部
 temp2=BigNum2.End;
 while(temp1 && temp2)
 {
  TempNum=int(temp1->Num)+int(temp2->Num)+rest;         //节点内元素相加并加上进位rest
  if(TempNum>9)                  //判断相加结果是否会产生进位.
  {
   TempNum=TempNum-10;
   rest=1;
  }
  else
   rest=0;
  result.AddHead(char(TempNum));          //将结果放置到最终结果链表里
  temp1=temp1->Prev;
  temp2=temp2->Prev;
 }
 if(temp2)temp1=temp2;
 while(temp1)
 {
  int(TempNum)=int(temp1->Num)+rest;           //节点内元素加上进位rest
  if(TempNum>9)
  {
   TempNum=TempNum-10;
   rest=1;
  }
  else
   rest=0;
  result.AddHead(char(TempNum));             //将结果放置到最终结果链表里
  temp1=temp1->Prev;
 }
 if(rest)
  result.AddHead(char(rest));                //考虑最后的进位是否存在,如果存在则存入链表的首部.
 return result;
}

BigInteger BigInteger::operator * (const BigInteger &BigNum2)     //对*进行重载
{
 BigInteger &BigNum1=*this,temp,result;
 Node *temp1,*temp2,*tempa,*tempb;
 int TempNum,rest,i=0,rest2;
 temp1=BigNum1.End;
 temp2=BigNum2.End;
 while(temp2)        //由乘数的存在与否判断是否去乘被乘数的每个位
 {
  rest=0;
  while(temp1!=NULL)
  {
   TempNum=int(temp1->Num)*int(temp2->Num)+rest;
   if(TempNum>9)
   { 
    rest=TempNum/10;                 //进位由相乘结果与10做商求得
    TempNum=TempNum%10;                 //由相乘结果与10求模取个位
   }
   else
    rest=0;
   temp.AddHead(char(TempNum));        //存入临时链表
   temp1=temp1->Prev;
  }
  if(rest!=0)temp.AddHead(char(rest));
  for(int k=i;k>=1;k--)temp.AddEnd(char(0));       //判断应该在链表后面补几个0
  i++;            //每次乘完后计数,用来下一次的补0
  temp1=BigNum1.End;             //把被乘数重新置到尾,用来让乘数下一次去乘每个元素
  temp2=temp2->Prev;              //将乘数取出链表的前驱
  tempa=result.End;                  //下面进行的是将每次乘数与被乘数的相乘结果累加放到最终链表里等待输出
  if(result.Head!=NULL)           //下面过程与"+"重载基本一样,只是多了对临时链表的置空,所以不在做详细的注释.
  {
   result.End=temp.Head;
   result.Head=NULL;
  }
  tempb=temp.End;
  rest2=0;
  while(tempa!=NULL && tempb!=NULL)
  {
   TempNum=int(tempa->Num)+int(tempb->Num)+rest2;
   if(TempNum>9)
   {
    TempNum=TempNum-10;
    rest2=1;
   }
   else
    rest2=0;
   result.AddHead(char(TempNum));
   tempa=tempa->Prev;
   tempb=tempb->Prev;
  }
  if(tempb)tempa=tempb;
  while(tempa)
  {
   int(TempNum)=int(tempa->Num)+rest2;
   if(TempNum>9)
   {
    TempNum=TempNum-10;
    rest2=1;
   }
   else
    rest2=0;
   result.AddHead(char(TempNum));
   tempa=tempa->Prev;
  }
  if(rest2)
   result.AddHead(char(rest2));
  if(temp.Head!=NULL)
  {
   temp.End=temp.Head;
   temp.Head=NULL;
  }
  tempb=NULL;
 }
 return result;
}

BigInteger BigInteger::operator = (const BigInteger &BigNum)          //对=号进行重载
{
 if(this==&BigNum)
  return *this;
 Node *p;
 TempNode=Head=End=NULL;
 p=BigNum.Head;
 while(p)
 {
  AddEnd(p->Num);
  p=p->Next;
 }
 return *this;
}

void BigInteger::disp()                    //输出链表
{
 if(Head)
 {
  cout<<int(Head->Num);
  TempNode=Head->Next;
 }
 else return;
 while(TempNode)
 {
  cout<<int(TempNode->Num);
  TempNode=TempNode->Next;
 }
 cout<<endl;
}
//main.cpp

#include <iostream.h>
#include "BigInteger.h"

void main()
{
 BigInteger BigNum1,BigNum2,BigNum3;
 int c;
 cout<<"选择你要进行的操作:"<<endl;
 cout<<"1.大整数加法运算"<<endl;
 cout<<"2.大整数乘法运算"<<endl;
 cout<<"选择你需要进行的运算:"<<endl;
 cin>>c;
 switch(c)
 {
  case 1:
   { 
    cout<<"A:"<<endl;
    BigNum1.GetNumber();
    cout<<"B:"<<endl;
    BigNum2.GetNumber();
    BigNum3=BigNum1+BigNum2;
    cout<<"相加的结果是:"<<endl;
    BigNum3.disp();
   }break;
  case 2:
   {
    cout<<"A:"<<endl;
    BigNum1.GetNumber();
    cout<<"B:"<<endl;
    BigNum2.GetNumber();
    BigNum3=BigNum1*BigNum2;
    cout<<"相乘的结果是:"<<endl;
    BigNum3.disp();
   }break;
  default:break;
 }
}

 

 

 

 

  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
### 回答1: 大整数加法乘法是计算机科学中常见的问题大整数通常比机器原生数据类型表示的整数要大得多,因此需要采用特殊的算法来进行计算。 首先,我们来实现大整数加法。假设我们有两个大整数num1和num2,我们需要从最低位开始逐位相,并且记录进位。具体的步骤如下: 1. 定义两个指针i和j分别指向num1和num2的最低位。 2. 初始化进位carry为0,并创建一个空的数组result用来存放结果。 3. 进行循环,直到指针i和j都越界: a. 将当前位的数字相上进位carry,并将结果存放在sum变量中。 b. 将sum对10取余的结果添到result数组中。 c. 更新进位carry为sum除以10的结果。 d. 更新指针i和j分别为下一位。 4. 如果carry不为0,将其添到result数组的最高位。 这样就完成了大整数加法。 接下来,我们来实现大整数乘法。同样地,我们需要从最低位开始逐位相乘,并且记录进位。具体的步骤如下: 1. 定义两个指针i和j分别指向num1和num2的最低位。 2. 初始化进位carry为0,并创建一个空的数组result用来存放结果。 3. 进行嵌套循环,外层循环遍历num1的每一位,内层循环遍历num2的每一位: a. 将当前位的数字相乘,上进位carry,并将结果存放在product变量中。 b. 将product对10取余的结果添到result数组中的对应位置。 c. 更新进位carry为product除以10的结果。 d. 更新指针j为下一位。 e. 将进位carry添到result数组的下一个位置。 f. 更新指针i为下一位,重置指针j为num2的最低位。 4. 如果carry不为0,将其添到result数组的最高位。 这样就完成了大整数乘法。 总结起来,大整数加法乘法都可以通过从最低位开始逐位相或相乘,并记录进位来实现。需要注意的是,使用数组来存放结果,可以处理大整数不同位数的情况。 ### 回答2: 大整数加法乘法实现可以使用字符串来表示大整数,并按照进位运算的方法进行计算。 大整数加法的步骤如下: 1. 将两个大整数的字符串表示形式补齐到相同长度,可以在较短的字符串前面补0。 2. 从字符串的末尾(个位)开始遍历,将对应位置的数字相。 3. 若相的结果大于等于10,则需要进位。将进位的数字到下一位的运算结果中。 4. 将每次相的结果依次一个新的字符串中。 5. 如果最高位相后有进位,则需要在最终结果的最前面上进位。 大整数乘法的步骤如下: 1. 遍历两个大整数的字符串表示,将第一个数的每一位与第二个数的每一位相乘。 2. 通过一个二维数组来保存相乘的结果,其中每一行表示第一个数的一位与第二个数相乘的结果,乘积的每一位按照对应的位数存储。 3. 对于乘积的每一位,先计算当前位置上的乘积结果,然后将前一位(进位)到当前位上。 4. 将每一位的结果依次一个新的字符串中。 5. 最后需要将每一位的结果按照进位的方式处理,直到最高位没有进位为止。 通过以上步骤,可以实现大整数加法乘法的功能。这种方法适用于任意长度的大整数计算,无需考虑整数的大小限制。 ### 回答3: 要实现大整数加法乘法,我们可以使用字符串来表示大整数,并模拟手工计算的过程进行运算。 对于加法,我们从个位开始按位相,如果有进位则向前一位进位,直到所有位数相完成,最后将结果拼接成新的字符串即可。 对于乘法,我们需要将每个位上的数字与另一个整数的每个位上的数字相乘,然后将结果按位相,也就是说,我们从被乘数的个位开始,与乘数的每一位相乘,然后将结果保留到相应的位置。在进行下一位的计算时,需要将之前的结果整体往前进一位,因为每一位的值是乘数的某一位与当前被乘数位相乘的结果。最后将所有位的结果相,得到最终的乘积。 需要注意的是,由于大整数可能会超过计算机能表示的范围,我们不能使用内置的整数类型进行运算,而要使用字符串来模拟整数的计算过程。在实现乘法时,还需要考虑到进位的情况。 总的来说,实现大整数加法乘法需要注意好运算顺序和进位的处理,通过模拟手工计算的过程,可以得到正确的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值