开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第22天,点击查看活动详情
如何存储一个大数据 : 把一个大数据放到数据当中去
为什么这样存储
原因是两个数相加或者相乘的时候,会产生进位,此时我们要在高位补上一个数,在数组后面插入一个数比在数组的前面插入一个数容易,如果在前面插入一个数,所有的数都要向后移一位
高精度加法
//C = A + B, A >= 0, B >= 0 其中低下标存的是数据的低位
vector<int> add(vector<int>& A, vector<int>& B)
{
vector<int> C;//存放相加结果
int carry = 0;//进位
for (int i = 0; i < A.size() || i < B.size(); i++)
{
//通过判断下标i ,是否在A,B中是有效位置,一遍通过
//ans = A[i] + B[i] + carry
int ans = carry;//本轮计算结果
if (i < A.size()) ans += A[i];
if (i < B.size()) ans += B[i];
C.push_back(ans % 10);
carry = ans / 10;//进位
}
if (carry == 1)//最后看一下最高位有没有进位,有进位就要补1
C.push_back(1);
//123+456 = 579 最后C中存储的就是:975
return C;
}
写法2:保证A数组是更长的数组,并且直接利用进位数,不用再定义一个变量
vector<int> add(vector<int> &A, vector<int> &B)
{
//保证A的长度是更长的,所以下面for可以省略一个条件:i<B.size() 数组低下标是低位
if (A.size() < B.size()) return add(B, A);
vector<int> C;
int carry = 0;//利用进位数,不用再定义一个变量存储
for (int i = 0; i < A.size(); i ++ )
{
carry += A[i]; //A数组是更长的
if (i < B.size()) carry += B[i];
C.push_back(carry % 10);
carry /= 10;
}
if (carry) C.push_back(carry);
return C;
}
高精度减法:
t:表示是否要向上一位借位,注意:我们这里要保证是大数 - 小数 ,即要保证:要保证A>=B
- 如果A<B 就去计算B-A 然后最后结果加个负号
- 假设计算结果为ans, 如果ans>=0 ,返回的是ans, 如果ans<0:返回的是ans+10
- 可以合并成一种情况: 返回 (ans+10)%10
注意:最后可能需要把前导0去掉,如:123-120=3, 最后数组存放的是300 (倒着存),需要把前导0去掉,变成3
判断A数组和B数组哪个更大
//判断是否有A>=B
bool cmp(vector<int>& A, vector<int>& B)
{
if (A.size() != B.size())
return A.size() > B.size();
//二者长度相等,需要判断谁更大,从数的高位开始判断 例如:判断999和998的大小
//数组中低下标存的是低位,所以倒着比较
for (int i = A.size() - 1; i >= 0; i--)
{
if (A[i] != B[i])
return A[i] > B[i];
}
return true;//二者相等
}
高精度减法
// C = A - B, 满足A >= B, A >= 0, B >= 0
vector<int> sub(vector<int>& A, vector<int>& B) //调用时要保证A数组更大
{
vector<int> C;
int t = 0;//借位
for (int i = 0; i < A.size(); i++)
{
//直接复用借位变量,当前这一位的计算值就是:t = A[i] - B[i] - t
t = A[i] - t;
if (i < B.size()) t -= B[i];
//如果此时的计算结果t>=0的话,就是t本身,如果<0的话,就返回t+10 (向上一位借位)
//上面两种情况合二为一: (t + 10) % 10
C.push_back((t + 10) % 10);
if (t < 0) //需要向上一位借位
t = 1;
else
t = 0;
}
//去掉前导0
//如果最后结果是0的话,就要保留这个0,所以必须保证C.size() > 1
while (C.size() > 1 && C.back() == 0)
C.pop_back();
return C;
}