高精度
a + b
思路
- 从最低位向前遍历
- 设置t为当前A的值加上当前B的值(前提是B存在)
- 将t%10压入C,然后t/10,重复1-2这个过程
- 如果t不为零,则将其压入C
- 如果A+B出现00000的情况,需删除前置0
核心代码
#include <iostream>
#include <vector>
using namespace std;
vector<int> add(vector<int> &A, vector<int> &B){
//确保A的长度 >= B的长度
if(A.size() < B.size())
return add(B, A);
vector<int> C;
int t = 0;
//从头遍历A
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;
//t设置为A[i]+B[i](B[i]存在)
//将t%10压入C,然后 t/10
}
if(t)//若t不为零,压入C
C.push_back(t);
return C;
}
int main(){
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);
for(int i = C.size() - 1; i >= 0; i --) cout << C[i];
return 0;
}
a - b
思路
- 首先比较a,b大小,确保大数减小数
- 因为A是逆序的,所以从头到尾进行遍历(即从最低位开始相减)
- 设置t为被减数 - 上一个数借的位
- 如果此时B长度在A的范围内,减去当前位置B的值,否则不减
- 将(t+10) % 10压入vectorC中,代表相减的结果,重复过程2-5
- 如果t<0,则需要向前借位,设置t=1,否则,t设为0
核心代码
#include <iostream>
#include <vector>
using namespace std;
//首先比较a,b大小,确保大数减小数
bool cmp(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;
}
vector<int> sub(vector<int> &A, vector<int> &B){
vector<int> C;
//因为A是逆序的,所以需要从头到尾遍历(即从最低位开始相减)
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;
//设置t为被减数 - 借位
//如果b长度仍在A的长度范围内,减去减数
//将(t+10)%10压入C中
//若t<0,则需借位1,否则无需借位设为0
}
while(C.back() == 0 && C.size() > 1) C.pop_back();
return C;
}
int main(){
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');
if(cmp(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];
}
return 0;
}
a * b
- 首先将字符串倒置,放入vectorA中
- 此时A是逆序,从第一位进行遍历
- 设t为前一位进位加上A[i]*b
- 将t%10压入vectorC,接着将t/10进行下一位计算,重复3-4此过程,直至A中元素遍历结束
- 若此时t仍不为零,将t%10压入vectorC,并c/10
- 可能会有结果全为0的情况(如12345*0=00000),因此需要删去其余0
- 最后输出时候注意逆序
核心代码
vector<int> mul(vector<int> &A, int b){
vector<int> C;
int t = 0;
//从第一位进行遍历
for(int i = 0; i < A.size(); i ++){
t += A[i] * b;
C.push_back(t % 10);
t /= 10;
//t为前一位加上A[i]*b
//将t%10压入C中,并除以10
}
//t仍不为零的情况
while(t){
C.push_back(t % 10);
t /= 10;
}
//结果全是0的情况
while(C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
代码优化
可以将t不为零的情况与A遍历合并
#include <iostream>
#include <vector>
using namespace std;
vector<int> mul(vector<int> &A, int b){
vector<int> C;
int t = 0;
//代码优化,合并遍历与t
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;
}
int main(){
string a;
int b;
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);
for(int i = C.size() - 1; i >= 0; i --) cout << C[i];
return 0;
}
a / b
- 首先将字符串倒置,放入vectorA中
- 此刻vectorA是倒置的,需从最高位进行运算
- 将上次的余数*10再加上当前位的数字,记为c
- 将c/b压入vectorC中
- 通过c%r取得余数放入c,并重复过程2~4直至数组A完全遍历结束
- 在第4步的时候将第一个数为0的情况放入了vectorC的第一个位置,需要将其逆置,移除0.
核心代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<int> div(vector<int> &A, int b, int &c){
vector<int> C;
//因为传入vectorA是倒置的,需从最高位进行运算
for(int i = A.size() - 1; i >= 0; i --){
c = c * 10 + A[i];
C.push_back(c / b);
c = c % b;
//将上次的余数*10再加上当前位的数字,记为c
//将c/b压入vectorC中
//通过c%r取得余数放入c,并重复过程
}
//在压入c/b的时候将首位为0情况压入了vectorC的第一个位置
//需要将其逆置,移除0.
reverse(C.begin(), C.end());
while(C.back() == 0 && C.size() > 1) C.pop_back();
return C;
}
int main(){
string a;
int b, c;
cin >> a >> b;
vector<int> A;
//将字符串逆置放入A中
for(int i = a.size() - 1; i >= 0; i --) A.push_back(a[i] - '0');
auto C = div(A, b, c);
//逆序输出C
for(int i = C.size() - 1; i >= 0; i --) cout << C[i];
cout << endl;
cout << c << endl;
return 0;
}