携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第1天,点击查看活动详情
AcWing 791. 高精度加法
给定两个正整数(不含前导 0),计算它们的和。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的和。
数据范围
1 ≤ 整数长度 ≤ 100000
输入样例:
12
23
输出样例:
35
思路
高精度加法
思路:将两个数字从个位相加到最高位
例子:567和28
567 要转为 765 放在数组中存储
28 要转为 82 放在数组中存储\
模拟手动加法计算即可。
例如计算:567 + 28
先个位相加: 7 + 8 = 15,所以结果的个位是5,向十位进 1
再十位相加: 6 + 2 + 1(进位)= 9, 所以十位是 9,向百位进 0
在百位相加: 5 + 0 = 5, 所以结果的百位是 5
计算 567 + 28
用 a, b 两个字符串存储输入。a = 567, b = 28
为了方便计算,将两个数分别 倒序 存放在 A, B 两个整数数组中。 A = [7, 6, 5], B = [8, 2]
新建整数数组 C 保存结果,整型变量 t 保存进位,初始 t = 0.
将各个位上的数字相加,求出结果对应位上的数字和进位。
例如对个位计算: A[0] + B[0] = 7 + 8 = 15, 结果个位上是 5, 进位是 1. 所以 C[0] = 5, 进位 t = 1
最后把结果数组 C 中就保存了计算倒序结果,倒序输出就是答案
然后逆序输出结果
高精度加法 A + B 从低到高位计算 c[i] = (A[i] + B[i] + t) % 10, 进位 t = (A[i] + B[i] + t) / 10; 计算完之后如果 t大于0,记得进位加到 c数组最后。
高精度加法模板
// C = A + B, A >= 0, B >= 0
vector<int> add(vector<int> A, vector<int> B){
if (A.size() < B.size()) return add(B, A);
vector<int> C;
int t = 0;
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;
}
if (t) C.push_back(t);
return C;
}
ac代码
#include<iostream>
#include<vector>
using namespace std;
vector<int> add(vector <int> A, vector <int> B){
vector<int> C;
int t = 0; //初始化 进位为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;
}
int main(){
string a,b;
cin>>a>>b;
vector<int> A,B;
for(int i = a.size() - 1;i >= 0;i--){ //将string数字倒序存放
A.push_back(a[i]-'0');
}
for(int i = b.size() - 1;i >= 0;i--){ //将string数字倒序存放
B.push_back(b[i]-'0');
}
auto C = add(A,B);
for(int i = C.size() - 1;i >= 0;i--){ //将string数字逆序输出
printf("%d",C[i]);
}
return 0;
}
AcWing 792. 高精度减法
给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。
输入格式
共两行,每行包含一个整数。
输出格式
共一行,包含所求的差。
数据范围
1 ≤ 整数长度 ≤ 10^5
输入样例:
32
11
输出样例:
21
思路
高精度减法
先用数组存储两个数字,存储方法和高精度加法一致
然后判断 a 和 b 两个数字的大小,从两个数字的长度(都为整数)开始比较,若相同则最高位开始判断然后依次比较,判断最后结果的正负
每次都要从数组的第一个位置开始循环计算,用 变量 t 来代替是否借位,和当前数位的结果,初始化为 0;a - t 计算借位的结果, t - b 表示 当前位置的计算结果,如果 t >= 0 表示 当前无需借位,否则需要借位 (t + 10) % 10 表示当前位置的结果,最后去掉数组后面最后的0
和高精度加法差不多,值得注意的是
减法的借位处理
相减为负数的处理
前导0的处理
对于 t = A[i] - B[i] - t; 可以拆为 t = A[i] - t如果B[i]合法,再t -= B[i] 这么两步来做
相减后t的处理 ,把 t >=0 和 t < 0 用一个式子来表示 t = (t + 10) % 10
高精度减法 A - B(注意需要保证 A >= B) 从低位到高位计算 c[i] = (A[i] - B[i] - t) >= 0 ? (A[i] - B[i] - t) % 10 : ((A[i] - B[i] - t) + 10) % 10, 借位 t = (A[i] - B[i] - t) >= 0 ? 0 : 1
高精度减法模板
// C = A - B, 满足A >= B, A >= 0, B >= 0
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;
}
ac代码
#include<iostream>
#include<vector>
using namespace std;
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;
for(int i = 0,t = 0;i < A.size();i++){
t = A[i] - t;// t 的 作用 1.判断是否借位了 2 作为当前循环计算的位数
if(i < B.size()){
t -= B[i];// 当前位置上的 a - b
}
C.push_back((t + 10) % 10);//消除符号的影响
if(t < 0){
t = 1;//如果小于,借位
}
else t = 0;
}
//结果为0XXXX类型,需要消除前导数0
while(C.size() > 1 && C.back() ==0) {
C.pop_back();//去掉前导0
}
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');
}
if (cmp(A,B)){
auto C = sub(A,B);
for(int i = C.size() - 1;i >= 0;i--){ //逆序
printf("%d",C[i]);
}
}else{
auto C = sub(B,A);
printf("-");
for(int i = C.size() - 1;i >= 0;i--){
printf("%d",C[i]);
}
}
return 0;
}