基础算法--高精度乘除法

3 阅读3分钟

高精度乘除法


高精度乘除法的大致思路和加减法差不多: 字符串读入--->倒着转化到nt数组中存储-->用数组去模拟乘法的竖式运算-->去掉前导0,倒着输出结果。

但是需要注意几点细节:

  1. n位数 * m位数,结果最多为m + n位
  2. b[i] * a[j] = c[i + j]

下面是代码示例:

#include <iostream>
#include <cmath>
#include <string>
using namespace std;
//两个不超过1万位的数相乘
int a[10005];
int b[10005];
int c[20005];

int init(int x[]){
    string s;
    cin >> s;
    int l = s.size();
    for(int i = 0; i < l; ++i){
        x[i] = s[l - 1 -i] - '0';
    }
    return l;
}

int main(){
    int la = init(a);
    int lb = init(b);
    int lc = la + lb;
    for(int i = 0; i < la; ++i){
        for(int j = 0; j < lb; ++j){
            c[i + j] += a[i] * b[j];
        }
    }

    //处理进位
    for(int i = 0; i < lc; ++i){
        if(c[i] >= 10){
            c[i + 1] += c[i] / 10;
            c[i] = c[i] % 10;
        }
    }
    
    //去掉前导0
    while(c[lc] == 0 && lc > 0){
        --lc;
    }
    for(int i = lc; i >= 0; --i){
        cout << c[i];
    }
    cout << endl;

    return 0;
}

对于高精度除法,比乘法要复杂一些,大致思路一样: 字符串读入--->倒着转化到nt数组中存储-->用数组去模拟乘法的竖式运算-->去掉前导0,倒着输出结果。

除法要注意以下几点细节:

  1. 较小的数除较大的数-->结果为0
  2. 较大的数除较小的数-->计算
  3. 除法的本质,其实是一次次的减法
  4. m位数除以n位数,商的位数位m - n + 1
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
//两个不超过1万位的数相除
//数组0下标存放数据长度
int a[10005];
int b[10005];
int c[20005];

void init(int x[]){
    string s;
    cin >> s;
    x[0] = s.size();
    for(int i = 1; i <= x[0]; ++i){
        x[i] = s[x[0] - i] - '0';
    }
}
bool check(int x[], int y[]){
    if(x[0] > y[0])return 1;
    if(x[0] < y[0])return 0;
    //长度相等
    for(int i = x[0]; i >= 1; --i){
        if(x[i] > y[i])return 1;
        if(x[i] < y[i])return 0;
    }
    return 1;//x = y
}

void sub(int x[], int y[]){
    for(int i = 1; i <= x[0]; ++i){
        if(x[i] < y[i]){
            x[i] += 10;
            x[i + 1] -= 1;
        }
        x[i] -= y[i];
    }
    //去除前导0
    int i = x[0];
    while(x[i] == 0 && i > 1){
        --i;
    }
    x[0] = i;
}

int main(){
    init(a);
    init(b);

    //去掉前导0,防止005 > 9的情况
    while(a[a[0]] == 0 && a[0] > 1){
        --a[0];
    }

    //去掉前导0
    while(b[b[0]] == 0 && b[0] > 1){
        --b[0];
    }

    if(check(a, b) == 0){//小数除大数
        cout << 0 << endl;
        return 0;
    }
    //商的位数
    c[0] = a[0] - b[0] + 1;
    for(int i = c[0]; i >= 1; --i){
        int t[10005] = {0};
        //在除数b的后面补i - 1个0,让b和a位数对齐 --> 存到t中
        for(int j = 1; j <= b[0]; ++j){
            t[i-1+j] = b[j];
        }
        t[0] = b[0] + i - 1;
    //减法模拟除法,算商
    while(check(a, t) == 1){
        sub(a, t);
        ++c[i];
    }

    }

	//去掉前导0
    while(c[c[0]] == 0 && c[0] > 1){
        --c[0];
    }
    for(int i = c[0]; i > 0; --i){
        cout << c[i];
    }
    cout << endl;

    return 0;
}

除法的过程比较复杂,大家可以借助AI,好好品味一下高精度除法的思想