25. 高精度乘/除法

123 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

高精度乘法

思路:

  • 高精度整数乘以低精度的整数,将较小的数看成整体,高精度整数的每一位,依次乘以低精度整数
  • 下一位与小的整数相乘,并且再加上进位。
  • 去掉前导0,因为结果可能是0123456

具体步骤

  1. 高精度整数A低精度整数b倒序排放在数组中
  2. 高精度整数的每一位,依次乘以低精度整数这个整体。
  3. 考虑进位,(A * b + t) %10 为结果,(A * b + t) / 10为进位.
  4. 去掉前导0,因为结果可能是0123456
  5. 将C中数数字,倒序打印输出。

举例:

1661149558217.png

1661149579051.png

代码

#include <iostream>
#include <vector>
using namespace std;

vector<int> mul(vector<int> &A, int b)
{
   vector<int> C;
   int t = 0;         //最开始的t0 = 0;
   for (int i = 0; i < A.size() || t; i ++)
   {
       if(i < A.size()) t += A[i] * b;
       C.push_back(t % 10);
       t /= 10;
   }
   
   while (C.size() > 1 && C.back() == 0) C.pop_back();  //去掉前导0;
   return C;
}

int main()
{
   string a;
   int b;
   cin >> a >> 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 --)printf("%d", C[i]);
}

核心算法可以改成:

vector<int> mul(vector<int> &A, int b)
{
   vector<int> C;
   int t = 0;         //最开始的t0 = 0;
   for (int i = 0; i < A.size() ; i ++)
   {
       t += A[i] * b;
       C.push_back(t % 10);
       t /= 10;                
   }                            
   if (t != 0) C.push_back(t);   //此时t有多种情况,可能为0(不进位),可能进位为1,也可能进位大于1
                                //加法这里只有俩种情况,要么进位,进位只进 1,要么不进位
   
   while (C.size() > 1 && C.back() == 0) C.pop_back();  //去掉前导0;
   return C;
}
## 高精度除法

思路:

  • 高精度整数除以低精度的整数,商为C,余数为r。
  • 从高位依次除以低精度整数。商(C)存在数组中,r * 10 + 后一位,继续除以低精度整数。一直循环结束。
  • 去掉前导0

步骤:

  1. 为了和之前的高精度加法、减法、乘法模板一致,这里也是采用倒序存储,唯一不同的点是,这里是从高位进行运算,而之前都是从低位进行运算

  2. 设置余数,初始值 为0,高精度整数从高位依次除以低精度整数,商(C)存在数组中,余数 r * 10 + 后一位,继续运算。

  3. 进行翻转(之前高精度整数 123 + 10,倒序存放在数组中,从低位运算 321 + 01。而乘法需要从高位运算,所以需要翻转一下 )

  4. 去掉前导 0

    1. 倒序打印

    举例1661149687439.png

代码

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// A / b,商是C, 余数是r
vector<int> div(vector<int> &A, int b , int &r) //r 是引用
{
   vector<int> C;
   r = 0;         
   for (int i = A.size() - 1; i >= 0; i --)
   {
       r = r * 10 + A[i];
       C.push_back(r / b);
       r %= b;
   }
   
   reverse(C.begin(), C.end());                         //翻转数组元素
   while (C.size() > 1 && C.back() ==0) C.pop_back();   //去掉前导0
   return C;
}

int main()
{
   string a;
   int b;
   
   cin >> a >> 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 --) printf("%d",   C[i]);
   cout << endl << r <<endl;
}