#include<iostream>
#include<vector>
using namespace std;
vector<int> add(vector<int>& A, vector<int>& B) {
if (A.size() < B.size()) return add(B, A);//保证A的位数大于B
int t = 0;
vector<int> C;
for (int i = 0; i < A.size(); i++) {
t += A[i];
if (i < B.size())t += B[i];//如果B加到最后一位,则不再加
C.push_back(t % 10);
t /= 10;
}
if (t) C.push_back(t);
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;
return 0;
}该算法的适用场景是超大数的加法运算
整体思路就是回想自己做加法时的步骤就可以了.
以下有几个值得注意的点:
1.保证A的位数大于B
2.存储算法时,从低位开始存储,(虽然会导致之后的高精度除法需要稍微多一些的操作,但是数据在计算的过程中应该遵守其源数据不变的原则)
#include<iostream>
#include<vector>
using namespace std;
bool sign;
vector<int> sub(vector<int>& A, vector<int>& B, bool sign) {
vector<int> C;
if (A.size() < B.size())return sub(B, A, false);//保证A>B
else if (A.size() == B.size()) {
for (int i = A.size() - 1; i >= 0; i--) {
if (A[i] < B[i])return sub(B, A, false);
else if (A[i] > B[i])break;
}
}
int t = 0;
for (int i = 0; i <= A.size() - 1; i++) {
t = A[i] - t;//减去借位
if (i < B.size())t -= B[i];
C.push_back((t + 10) % 10);//若t<0则借位,若t>0,则与%10抵消
if (t < 0) t = 1;
else t = 0;
}
while (C.size() > 1 && C.back() == 0)C.pop_back();
if (!sign)C.push_back(-1);
return C;
}
int main()
{
sign = true;
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');
vector<int> C;
C = sub(A, B, sign);
if (C.back() == -1) {
cout << "-";
C.pop_back();
}
for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
cout << endl;
return 0;
}
该算法的适用场景是超大数的减法运算
需要注意的有以下几点:
1.该算法会存在符号问题,我们需要保证A大于B,如果存在调换,我们就会把最终结果加上负号
减法会比加法稍微复杂一些,本算法没有考虑两个负数相减的情况是因为,在任何情况下的加减的问题,都可以把问题转化成|A|+|B|或者 |A|-|B|的形式,这个问题是可以通过对输入端的判断来解决的,所以该算法不存在漏洞
版权声明:本文为qq_52810376原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。