目录
一、高精度加法
1. 算法原理
当输入的数很大时,可采用字符串方式接收。
拆成一位一位的数字,把它们存在一个数组中,一个数组元素表示一位数字。
数组中是这样存储的:

【倒序存储原因】
这是因为加法可能会产生进位,而数组在最前面加上数字是不可能的,但在尾巴处加上数字是好做的,所以倒着放。

2.应用
(输入为正整数)
#include<iostream>
#include<vector>
using namespace std;
class Hp_Add
{
public:
void hp_add()
{
string a, b;
cin >> a >> b;
vector<int> 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);
cout << "sum:>";
for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
}
private:
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;
}
if (t) C.push_back(1);
return C;
}
};
二、高精度减法
(输入为正整数)
减法需要解决两数大小所导致的正负号的问题。
#include<iostream>
#include<vector>
using namespace std;
class Hp_Sub
{
public:
void hp_sub()
{
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');
// 去除前置的0
while (A.size() > 1 && A.back() == 0) A.pop_back();
while (B.size() > 1 && B.back() == 0) B.pop_back();
if (sign(A, B))
{
auto C = _sub(A, B);
for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
}
else
{
auto C = _sub(B, A);
cout << '-';
for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
}
}
private:
vector<int> _sub(vector<int>&A, vector<int>&B)
{
vector<int> 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;
}
// 判断大小
bool sign(vector<int>&A, vector<int>&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;
}
};
三、高精度乘法
相比于加法与减法,乘法需要注意进位问题(进位数超过原数的最大位数),要将遍历条件修改为 i < A.size() || t 。
#include<iostream>
#include<vector>
using namespace std;
class Hp_Mul
{
public:
void hp_mul()
{
int b;
string a;
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);
// 去除前置的0
while (A.size() > 1 && A.back() == 0) A.pop_back();
for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
}
private:
vector<int> _mul(vector<int>& A, int b)
{
vector<int> C;
// 注意当t不为0时,不结束循环
for (int i = 0, t = 0; i < A.size() || t; ++i)
{
if (i < A.size()) t += A[i] * b;
C.push_back(t % 10);
t /= 10;
}
return C;
}
};
四、高精度除法
引用了 reverse() 函数【采用头文件algorithm】来对储存商的vector进行逆置,从而解决前置 0 的问题。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Hp_Div
{
public:
void hp_div()
{
string a;
int b, c = 0;
vector<int> A;
cin >> a >> b;
for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');
while (a.size() > 1 && a.back() == 0) a.pop_back();
auto C = _div(A, b, c);
for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
// 返回余数
if (c) cout << "……" << c << endl;
}
private:
vector<int> _div(vector<int>& A, int b, int& c)
{
vector<int> C;
int r = 0;
for (int i = A.size() - 1; i >= 0; --i)
{
r = r * 10 + A[i];
C.push_back(r / b);
r %= b;
}
// 去除商的前置0
reverse(C.begin(), C.end());
while (C.size() > 1 && C.back() == 0) C.pop_back();
c = r;
return C;
}
};
9807

被折叠的 条评论
为什么被折叠?



