文章目录
一:原理分析
1.高精度问题介绍
问题: 当需要大整数(大于 Long Long的数据范围,例如123456789123456789123456789…)参与乘法时,我们该如何处理?
例如: 当 a=123456789123456789123456 b=1234567
请计算a * b ,或者a * a的结果的时候这时候我们应该如何处理这个问题呢?
2.高精度问题分析
分析: 首先我们分析为什么电脑不能处理大整数的乘法问题呢?答案是显然的,就是我们的整数空间无法存储这么长的整数,所以不能进行存储计算。
解决: 我们可以利用一个数组或者Vector容器来存储大整数,这样就可以存储下来这个大整数了,然后再根据我们乘法的原理去逐个选取Vector容器当中的数字出来然后进行计算即可。
3.高精度问题细节注意
a.高精度保存Vector容器
高精度保存:使用vector容器保存,并且将高位放在容器后面逆序保存。
原因: 如果开始将高位按顺序直接放入vector容器当中保存,可以直到当出现乘法数字进位的时候,我们其实很不方便在vector容器最前面加入新的数字,而vector容器在最后面加入数字是相对简单的,即逆序保存是为了方便乘法出现进位的时候进行进位加入新的数字。
b.进位的处理方式
高精度*低精度(低精度:数字大小不大,不必要使用Vector保存):处理方式用sum保存当前位乘积+小位所带来的进位和,利用sum%10即可得到当前位的大小,再用sum=sum/10让其进行进位继续计算
高精度*高精度:不能直接使用sum的方法进行处理,因为在高精度乘法的高位的时候可能是由多组数字乘积所得到的结果,不同于低精度可以一次性乘完数字b立即得到结果。
处理方法:先开一个Vector容器存放结果位,即先保存当前结果位的总和,再使用进位进行相应的处理
c.结果处理前导0
前导0:为避免0和其他数字相乘得到多个数字0,或者是本身Vector初始化的0,所以需要删除多余的前导0,保证数字的合法性.
二:高精度*低精度代码实现
1.代码解析
a:将高精度数字进行逆序保存: 利用Vector容器反向保存将低位存到前面
string s;
cin>>s;
//从低位开始按顺序保存
for(int i=s.size()-1;i>=0;i--) a.push_back(s[i]-'0');
b:乘法过程实现:逐步相乘,逐步得到每一位的结果保存到新的Vector容器当中再传回
vector<int> mul(vector<int>a,int b){
vector<int> c;
int sum=0;
// i<a.size()||sum 为了保证最后还有sum值需要进位可以继续往前进位
for(int i=0;i<a.size()||sum;i++){
if(i<a.size())sum+=a[i]*b;
c.push_back(sum%10);
sum/=10;
}
return c;
}
c:删去前导0:保证Vector[ ]长度大于1的情况下删去所有前导0
// 利用pop_back()函数不断删除前导0
while(c.size()>1&&c.back()==0) c.pop_back();
d:答案输出:因为是逆序保存的,所以最后也要从Vector[ ]容器的尾部先输出
//先输出Vector[]后面部分,即低位部分
for(int i=c.size()-1;i>=0;i--) cout<<c[i];
2.完整代码+运行结果
代码部分:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
vector<int> mul(vector<int>a,int b){
vector<int> c;
int sum=0;
for(int i=0;i<a.size()||sum;i++){
if(i<a.size())sum+=a[i]*b;
c.push_back(sum%10);
sum/=10;
}
while(c.size()>1&&c.back()==0) c.pop_back();
return c;
}
int main(){
vector<int> a,c;
string s;
int b;
cin>>s>>b;// 输入部分
for(int i=s.size()-1;i>=0;i--) a.push_back(s[i]-'0');
c=mul(a,b);
cout<<"高精度*低精度结果为:"<<endl;
for(int i=c.size()-1;i>=0;i--) cout<<c[i];
}
结果展示: a=123456789,123456789,123456789 b=23
三:高精度*高精度代码实现
1.代码解析
a:相对于高精度:低精度只在乘法过程实现多了一步提前求每位的和的结果这一部分
//先提前开一个足够大的空间来保存每位存储的结果
//空间大小为:a.size()+b.size()+10 并且预处理全赋值为0
vector<int> c(a.size()+b.size()+10,0);
// 先将每位上面的数字和进行一个求解
// 逐步去算每两位相乘的结果,影响的结果位=i+j
for(int i=0;i<a.size();i++){
for(int j=0;j<b.size();j++)
c[i+j]+=a[i]*b[j];
}
2.完整代码+运行结果
代码部分:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
vector<int> mul(vector<int>a,vector<int>b){
vector<int> c(a.size()+b.size()+10,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 sum=0;
for(int i=0;i<c.size();i++){
sum+=c[i];
c[i]=sum%10;
sum/=10;
}
while(c.size()>1&&c.back()==0) c.pop_back();
return c;
}
int main(){
string s;
vector<int> a,b,c;
cin>>s;
for(int i=s.size()-1;i>=0;i--) a.push_back(s[i]-'0');
cin>>s;
for(int i=s.size()-1;i>=0;i--) b.push_back(s[i]-'0');
c=mul(a,b);
cout<<"高精度*高精度结果为:"<<endl;
for(int i=c.size()-1;i>=0;i--) cout<<c[i];
}
结果展示:
a=123456789,123456789,123456789
b=123456789,123456789,123456789