算法基础课:高精度
高精度
高精度大数存储
因为运算时涉及到进位,故而当输入一个大整数,将其存储在可变数组时,需要倒过来存储。
如:123456789,存储为[9,8,7,6,5,4,3,2,1],进位时push_back(),删除时pop_back()
C++实现
// 大数存储
#include
#include
using namespace std;
int main () {
string a, b; // 作为大数的输入
vector A, B; // 使用2个动态数组存储
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');
return 0;
}
高精度加法
算法
- 模拟加法的过程,通过进位的t,实现每一位的加法
- t % 10 即此时的余在这一位的数
- t / 10,为 1 则进位,为 0 则无进位
- 在A、B最后一位加法结束后,判断有没有进位,即可返回加法后的结果
C++实现
vector add(vector &A, vector &B) {
vector 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;
}
if (t) C.push_back(t);
return C;
}
高精度减法
算法
- 先通过 cmp() 比较两个动态数组谁大谁小,再通过 sub() 函数进行减法操作
- 传入sub()的数,通过判断大小,始终是用大减小
- 先将当前位的A[i] - t,减掉借位的值,如果没有借位即为减 0借了位则减 1,再将 t赋值为它去具体的减当前位的B[i]
- 如果B还有值,那么这一位的C[i] 存的是 t - B[i] 的值 加上 10(模) 再取模,即如果 t小于 B[i] 那么就从上一位借位,如果t 大于 B[i] ,这个 + 10 % 10 的操作还是原来的值
- 如果 t - B[i] < 0,即从上一位借位了,那么把t 置为 1,在下一步的时候 A[i + 1] 要减去1,如果其 大于 0,则t = 0,表示没有借位。
- 最后再把结果动态数组C的高位的0去掉(因为借位后,可以高位会置为 0)
C++实现
bool cmp(vector &A, vector &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;
}
vector sub(vector &A, vector &B)
{
vector C;
for (int i = 0, t = 0; i < A.size(); i ++ )
{
t = A[i] - t;
if (i < B.size()) t -= B[i];
C.push_back((t + 10) % 10);
if (t < 0) t = 1;
else t = 0;
}
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
高精度乘法
算法
- 这里是大整数 * 普通整数
- 令 t = A[i] * b,C为这里的乘机取余 t % 10,进位 t /= 10
C++实现
vector mul(vector &A, int b)
{
vector C;
int t = 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();
return C;
}
高精度除法
算法
- 使用一个大整数除以一个普通整数
- 模拟除法过程,从高位除起,余数 * 10 和 下一位相加 再除以 b
- 具体的操作为 r为上一位的余数,到操作位时:r = r * 10 + A[i]
- 这一位的除的积为 r / b,得到余数为 r %= b
C++实现
vector div(vector &A, int b, int &r)
{
vector 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();
return C;
}