算法刷题(5)——高精度运算

97 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

这篇文章主要对于高精度的加减乘除运算进行一个讲解。

高精度加法

我们先来看一下题目。

image.png

输入样例

12 23

输出样例

35

参考代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
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/=10; //进位数取1 or 0
	}
	if(t){
		C.push_back(1);//加完后有进位就在最高位处添加1
	}
	return C;
	
}
int main()
{
    string a,b;
    vector<int> A,B;
    cin>>a>>b;
    for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0');
    for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0');
    auto C = add(A,B);
    for(int i=C.size()-1;i>=0;i--){
		cout<<C[i];
	}
	cout<<endl;
}

题目解析

这道题我们首先需要知道,题目条件中所给的两个数可以是很大的,因此不能直接用整型或长整型相加减。对于这种数据量较大的数,我们可以设法把它们存储到数组中,然后进行加减运算。

在本题中,我们可以定义两个数组用于存储被加的两个数,在这里是采用倒序存储,将数的每一位依次存放在数组中,然后将两个数组的每一位对应相加,得到的新的每一位数,最后将所有新的位数在按倒序(因为之前是倒过来了,现在要倒回去,恢复原状)存入最终的答案数组C中,即得到结果。

在进行数组相加这个算法的实现中,由于加法不可避免要涉及到进位,首先我们要设置进位数t,并且t只有1和0两种取值(进位取1,否则取0)。然后将被加的两个数的各个位依次对应相加。在这里用到了一个比较巧妙的方法,因为进位数t初始值为0,所以为了方便之后进位,就每一位的最终数t=t+A[i]+B[i](各位对应的数相加再加进位数),加完之后判断是否需要进位(t>10?)如果要进位,那么进位数t就为1,否则为0。每个位全部加完后,判断最高位是否需要进位,如果需要就在最高位处添上1。这就是整个运算过程。

模板归纳

// C = A + B, A >= 0, B >= 0
vector<int> add(vector<int> &A, vector<int> &B)
{
    if (A.size() < B.size()) return add(B, A);//进行了简化,和上面的代码略有不同

    vector<int> C;
    int t = 0;
    for (int i = 0; i < A.size(); i ++ )
    {
        t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }

    if (t) C.push_back(t);
    return C;
}

高精度加法其实主要考虑对各位按序相加的处理以及对进位的处理。之后我们将开始对高精度减法的内容进行介绍。