大整数高精度(C++没有大整数类,ACWing算法基础)

本文详细介绍如何使用数组存储大整数,并通过示例代码演示了大整数加法、减法、乘法及除法的具体实现过程。适用于解决计算机中超过常规整型变量所能表示的大整数运算问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

高精度题目类型

假定A和B为正数,大整数A、大整数B,A和B的位数大概是10^6。

  1. A-B
  2. A+B
  3. A*a(a为比较小的数)
  4. A/a

解题思路

1、大整数的存储

在这里插入图片描述
使用一个数组存储大整数,最低位下标为0

2、 模拟加法运算
在这里插入图片描述
每一位计算包含计算Ai+Bi+t(下一位的进位为0或者1),Ai或者Bi不存在就置0,最后如果有进位高位补1。

代码实现

1、大整数加法

#include<iostream>
#include<vector>//使用 vector表示大整数
using namespace std;
const int N = 1e6 +10;//1e6表示10^6,加10是为了防止边界问题



//加引用是为了提高效率,否则每执行一次函数数组都会被复制一遍
vector<int> add(vector<int> &A,vector<int> &B)
{
  vector<int> C;
  int t=0;//进位
  for(int i=0;i<A.size()||i<B.size();i++)
  {
     if(i<A.size())t+=A[i];
     if(i<B.size())t+=B[i];//超出了长度就不对其进行加法运算
     C.push_back(t%10);
     t=t/10;
  }
  if(t) C.push_back(1);
  return C;
}
或者
//加引用是为了提高效率,否则每执行一次函数数组都会被复制一遍
vector<int> add(vector<int> &A,vector<int> &B)
{
  vector<int> C;
  int t=0;//进位
  if(A.size()<B.size()) return add(B,A);
  for(int i=0;i<A.size();i++)
  {
     t+=A[i];
     if(i<B.size())t+=B[i];//超出了长度就不对其进行加法运算
     C.push_back(t%10);
     t=t/10;
  }
  if(t) C.push_back(1);
  return C;
}


int main()
{
   string a,b;
   vector<int>A,B;
   
   cin>>a>>b;//a="123456"
   //1、大整数使用数组存储
   //逆序存放
   for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');//A=[6,5,4,3,2,1]
    for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
   //2、模拟加法
   // auto让编译器自己推断变量是什么类型
   auto C = add(A,B);
   //倒序输出
   for(int i=C.size()-1;i>=0;i--)
   {
     printf("%d",C[i]);
   }
   return 0;
}

2、大整数减法
在这里插入图片描述在这里插入图片描述

#include<iostream>
#include<vector>//使用 vector表示大整数
using namespace std;
const int N = 1e6 +10;//1e6表示10^6,加10是为了防止边界问题

//判断A>=B?true:false
bool cmp(vector<int> A,vector<int> B)
{
   //位数不相同的情况下
   if(A.size()!=B.size()) return A.size()>B.size();
   //位数相同的情况下,从最高位开始比较
   for(int i=A.size()-1;i>=0;i--)
   {
      if(A[i]!=B[i])
      {
       return A[i]>B[i];
      }
   }
   return true;//A=B
}

//加引用是为了提高效率,否则每执行一次函数数组都会被复制一遍
vector<int> sub(vector<int> &A,vector<int> &B)
{
  vector<int> C;
  int t=0;//借位
  //从低位开始进行减法运算
  for(int i=0;i<A.size();i++)
  {
     t=A[i]-t;
     if(i<B.size())t-=B[i];//超出了长度就不对其进行减法运算
     C.push_back((t + 10) %10);//t>0进行加10模10运算还是本身;t<0就进行了借位操作
     if(t<0) t=1;
     else t=0;
  }

  //去掉前导0
  // 如果C为0,必须要保留
  //vector的back函数返回最末一个元素,pop_back移除vector中的最后一个元素
  while(C.size()>1&&C.back()==0)
  {
    C.pop_back();
  }
  return C;
}



int main()
{
   string a,b;
   vector<int>A,B;
   
   cin>>a>>b;//a="123456"
   //1、大整数使用数组存储
   //逆序存放
   for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');//A=[6,5,4,3,2,1]
    for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
   //2、模拟减法
   if(cmp(A,B))//
   {
   auto C = sub(A,B);
   //倒序输出
   for(int i=C.size()-1;i>=0;i--)
   {
     printf("%d",C[i]);
   }
   }
   else
   {
    auto C = sub(B,A);
    printf("-");
     //倒序输出
   for(int i=C.size()-1;i>=0;i--)
   {
     printf("%d",C[i]);
   }
   }
   
   
   return 0;
}

3、大整数乘法
在这里插入图片描述

#include<iostream>
using namespace std;
vector<int> mul(vector<int> &A,vector<int> B)
{
  int t=0;
  vector<int> C;
  //||t是考虑到最后最高位仍有进位的情况
  for(int i=0;i<A.size()||t;i++)
  {
    if(i<A.size())t+=A[i]*b;
    C.push_back(t%10);
    t/=10;
  }
  return C;
}
int main()
{
  string a;
  int b;//小整数
  vector<int> A;
  
  for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]='0');
  auto C=mul(A,b);
  for(int i=C.size()-1;i>=0;i--)prinf("%d",c[i]);
  return 0;
}

4、高精度整数除以低精度整数
在这里插入图片描述
在这里插入图片描述

#include<iostream>
#include<algorithm>
using namespace std;
vector<int> div(vector<int> &A,int &b,int &r)
{
  vector<int> C;
  
  //从最高位开始算
  for(int i=A.size()-1;i>=0;i--)
  {
    r=r*10+A[i];
    C.push_back(r/b);
    r=r%b;
  }

  reverse(C.begin(),C.end());
  // C数组应该从低位开始存
  //reverse在#include<algorithm>头文件
  
  while(C.size()>1&&C.back()==0) C.pop_back();//去掉前导0
}
int main()
{
  string a;
  int b;//小整数
  vector<int> A;
  
  for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]='0'); 
  
  int r;//余数
  auto C=div(A,b,r);

  for(int i=C.size()-1;i>=0;i--)prinf("%d",c[i]);
  cout<<endl;
  cout<<r<<endl;
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值