(1)高精度加法
首先,对字符串进行处理
string a,b;
cin>>a>>b;
vector<int>A(a.size());
vector<int>B(b.size());
for(int i=0;i<a.size();i++)A.push_back(a[i]-'0');
for(int i =0;i<.size();i++)B.push_back(b[i]-'0');
转换为vector数组并倒转数字{
//为什么?:1.在处理加法时,如果顺序存储,最高位就是A[0],如果最高位要进位,需要在a[0]前加一个数,显然会很麻烦(要移动数组每一位),换一种想法,只需要将数字倒过来相加,最高位在数组最末位,进位时只需要在数组最后添加一个数,显然大大提升了效率
接下来处理高精度加法函数
vector<int> add(vector<int> &A,vector<int> &B){
vector<int>C;
int carry=0;//处理进位
for(int i=0;i<A.size()||i<B.size();i++){
if(i<A.size())carry+=A[i];
if(i<B.size())carry+=B[i];
C.push_back(carry%10);
carry/=10;
}
if(carry!=0)C.push_back(carry);
return C;
}
将ab的每一位拿出来相加,存储carry的个位数存入C数组即可,假设从开始相加,carry为0,此时a与b的个位数相加,没进位,直接存入carry/=10;carry归零,如果进位,将carry个位数取出存入后,carry/=10;将进位存储在下一次加法的初始carry中,即可完成进位
最后,输出总结:
#include <bits/stdc++.h>
using namespace std;
// 高精度加法:C = A + B
vector<int> add(vector<int> &A, vector<int> &B) {
vector<int> C;
int carry = 0; // 进位
for (int i = 0; i < A.size() || i < B.size(); i++) {
if (i < A.size()) carry += A[i];
if (i < B.size()) carry += B[i];
C.push_back(carry % 10);
carry /= 10;
}
if (carry) C.push_back(carry); // 最后的进位
return C;
}
int main() {
string a, b;
cin >> a >> b;
// 转换为vector,低位在前
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');
vector<int> C = add(A, B);
// 输出结果(从高位到低位)
for (int i = C.size() – 1; i >= 0; i–) cout << C[i];
cout << "\\n";
return 0;
}
(2)高精度减法
第一步与加法相同,存储数字进入数组即可
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');
接下来,写一个函数判断a,b大小再进行减法
bool compare(string a, string b) {
if (a.length() != b.length())
return a.length() > b.length();
return a > b;
}
接下来我们写减法函数,对于减法函数,在这里我们只考虑a>=b的情况,因为我们的vector数组不能存储负数,对于a<b的情况,我们在主函数中分情况讨论,a<b时,就交换计算b-a的情况,然后再添加负号
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]; // 再减去B[i]
C.push_back((t + 10) % 10); // 结果
t = t < 0 ? 1 : 0; // 如果t<0,需要借位
}
// 去掉前导零
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
为什么要(t+10)%10?:这是因为在减法的时候有两种情况,这一位够减了,对于+10再%10没有影响,而这一位不够减时,加10再%10就是向前借一位再减
前导零?:在减法时,可能会出现减法后由原本的位数减为少一位的情况,这时候就会产生前导零
最后,减法模板
#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;
}
// 高精度减法 A – B(要求 A >= B)
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]; // 再减去B[i]
C.push_back((t + 10) % 10); // 结果
t = t < 0 ? 1 : 0; // 如果t<0,需要借位
}
// 去掉前导零
while (C.size() > 1 && C.back() == 0) C.pop_back();
return C;
}
int main() {
string a, b;
vector<int> A, B;
cin >> a >> b;
// 读取A(倒序存储)
for (int i = a.length() – 1; i >= 0; i–)
A.push_back(a[i] – '0');
// 读取B(倒序存储)
for (int i = b.length() – 1; i >= 0; i–)
B.push_back(b[i] – '0');
// 判断大小并计算
if (cmp(A, B)) {
vector<int> C = sub(A, B);
for (int i = C.size() – 1; i >= 0; i–)
cout << C[i];
} else {
cout << "-";
vector<int> C = sub(B, A);
for (int i = C.size() – 1; i >= 0; i–)
cout << C[i];
}
return 0;
}
(3)高精度乘法
高精度乘法一般分两种,一种高精度X低精度,一种高精度X高精度
1.高精度×低精度
这种比较简单,列出处理进位即可
与前面几种类似;
#include<iostream>
#include<vector>
using namespace std;
vector<int> multiply(const vector<int>&A,long long b) {
vector<int> C;
long long t=0;
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;
long long b;
cin>>a>>b;
vector<int>A;
for(int i=a.size()-1;i>=0;i–)A.push_back(a[i]-'0');
vector<int> ans=multiply(A,b);
for(int i=ans.size()-1;i>=0;i–)cout<<ans[i]<<" ";
return 0;
}
2.高精度×高精度
这里有一个比较重要的地方:竖式乘法中A的第i位置乘以B的第j位得到的数字应该在第i+j位置上,其余基本与前几项相同,不过要单独处理进位
#include<iostream>
#include<vector>
using namespace std;
vector<int> multiply(const vector<int>&A,const vector<int>&B) {
vector<int>C(A.size()+B.size(),0);
for(int i=0;i<A.size();i++) {
for (int j=0;j<B.size();j++) {
C[i+j]+=A[i]*B[j];
}
}
int t=0;
for (int i=0;i<A.size()+B.size();i++) {
t+=C[i];
C[i]=t%10;
t/=10;
}
while (C.size()>1&&C.back()==0)C.pop_back();
return C;
}
int main() {
string a,b;
cin>>a>>b;
vector<int>A;
vector<int>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>ans=multiply(A,B);
for (int i=ans.size()-1;i>=0;i–)cout<<ans[i]<<" ";
return 0;
}





