C++实现高精度加法:
对两个(大)正整数A,B相加,输出A+B结果
思想:"列竖式"
思路:
①读入字符串a,b
因为C++读入数字无法自动把每一位分开,只能先以字符串形式存取再处理
②将字符数组a,b处理为整形数组A,B
这里用vector数组更有优势,可直接读出长度且无需自己初始化长度
注:倒序读入
③参照“列竖式”的思想实现每一位加法,注意进位
核心:
A,B的读取处理和进位的处理
ps:这里未讨论负数的情况,在后续补充上高精度减法后更新
附上代码:
//正整数的高精度加法
#include<iostream>
#include<vector>
using namespace std;
vector<int> A, B, C;
vector<int> add(vector<int>& A, vector<int>& B) //传入地址就避免了拷贝原数组,速度更快
{
//为简化算法,只讨论len(A)>=len(B)的情况,这样子就不用在讨论位数上考虑太多
if (A.size() < B.size()) return add(B, A);
vector<int> C;
int t=0;//t存储A,B的某位的和
for (int i = 0; i < A.size(); i++)
{
t += A[i]; //+=是因为还有前一位的进位
if (i < B.size()) t += B[i]; //判断B[i]是否存在
C.push_back(t % 10); //保留t的个位,剩余的进位
t /= 10; //留进位
}
if (t) C.push_back(t); //最后总位数进一
return C;
}
int main()
{
string 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--) printf("%d", C[i]);
return 0;
}
C++实现高精度减法:
对两个(大)正整数A,B相减,输出A-B结果
思想:"列竖式"
思路:(和高精度加法类似)
①读入字符串a,b
因为C++读入数字无法自动把每一位分开,只能先以字符串形式存取再处理
②将字符数组a,b处理为整形数组A,B
这里用vector数组更有优势,可直接读出长度且无需自己初始化长度
注:倒序读入
③参照“列竖式”的思想实现减法,注意借位(为了简化,只讨论A>B的情况,如果A<B,先输出负号再交换A,B即可)
核心:
借位:如果对于某一位t+=A[i]-B[i]<0了,那么说明要借位,借位后留下C[i]=(t+10)%10,然后给t赋值-1以实现在计算下一位“借位”,
附上代码:
//正整数的高精度减法
#include<iostream>
#include<vector>
using namespace std;
vector<int> A, B, C;
bool cmp(vector<int>& A, vector<int>& B)
{
//A>=B,返回1 A<B,返回0
if (A.size() > B.size()) return true;
else if (A.size() == B.size())
{
//从高位开始一位位比
for (int i = A.size() - 1; i >= 0; i--)
{
if (A[i] > B[i]) return true;
else if (A[i] < B[i]) return false;
}
return true;
}
else return false;
}
vector<int> sub(vector<int>& A, vector<int>& B)
{
vector<int>C;
int t = 0;
for (int i = 0; i < A.size(); i++)
{
t += A[i];
if (i < B.size()) t -= B[i]; //只有B还有第i位时才减
//对于t<0,保留(t+10)%10;对t>0,(t+10)%10=t%10 将两种情况并到一起
C.push_back((t + 10) % 10);
//借位
if (t < 0) t = -1;
else t =0;
}
//处理前导0
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main()
{
string 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)) //A>=B
{
C = sub(A, B);
}
else
{
//结果为负数
printf("-");
C = sub(B, A);
}
for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
return 0;
}
延伸:
对于整数间的高精度加减法,实际上均可以转化为正整数间的高精度加减法:
① | ② | ③ | ④ | |
A | + | - | + | - |
B | + | - | - | + |
add | add(A,B) | '-'add(A,B) | sub(max{A,B},min{A,B}) |
① | ② | ③ | ④ | |
A | + | - | + | - |
B | + | - | - | + |
subtract | sub(max{A,B},min{A,B}) | 即-A+B(参考加法③④) | add(A,B) | ’-‘add(A,B) |