当我们遇到很大很大的数时就要用到高精度
#include
using namespace std;
string s1,s2;
int a[10000],b[10000],c[10000];
//反转转换
void zhuanhuan(string s,int a[]){
for(int i=0;i>s1>>s2;
zhuanhuan(s1,a);
zhuanhuan(s2,b);
int la=s1.size(),lb=s2.size();
int lc = max(la,lb)+1;
//相加
for(int i=1;i<=lc;i++){
c[i]=a[i]+b[i]+c[i];
c[i+1]=c[i]/10;
c[i]=c[i]%10;
}
//去多余的零
while(c[lc]==0&&lc>1) {
lc--;
}
for(int j=lc;j>0;j--){
cout<
1.首先先来了解下整体的一个操作,拿到两个字符串后,我们首先要把它转为int类=类型并加以反转,然后进行相加操作,去零操作,最后倒序输出出来。
2.(1)int lc = max(la,lb)+1;
首先我们要明确两个很大的数相加所得会有几位,这里有两种情况,一个是和两个数中大的数一样,另一种情况就是比两个数中大的那个数大一位,这里我们取第二种情况,lc之后还可以处理。
(2)c[i]=a[i]+b[i]+c[i];
c[i+1]=c[i]/10;
c[i]=c[i]%10;
代码核心部分:两个数相加过程,此时我们取到的是反转后的数字,首先c[i]=a[i]+b[i]+c[i],第一位数进行相加。c[i+1]=c[i]/10,这一步是将两数相加的进位给到第二位数。c[i]=c[i]%10,这一步是将两数相加的个位留在第一位,当进入下一个循环后,c[i]=a[i]+b[i]+c[i]这一步会将这位相加的两个数和进位加到一起,以此循环。
(3)在全部相加完后可能会在最后有零,反转后零就到了前面,所以要进行去零操作。最后反转输出就行。
#include
using namespace std;
string s1,s2;
int a[100],b[100];
//反转并且将字符串转为数字存到数组
void strtoint (string str,int arr[]){
for(int i=0;i=s2.size();
else return s1>=s2;
}
int main(){
int c[100];
cin>>s1>>s2;
if(cmpstr(s1,s2)==false){
swap(s1,s2);
cout<<"-";
}
strtoint(s1,a);
strtoint(s2,b);
int la = s1.size(),lb=s2.size();
int lc = max(la,lb);
//进行借位相减
for(int i=1;i<=lc;i++){
if(a[i]1) lc--;
for(int j=lc;j>0;j--){
cout<
1.整体操作和上题类似,就是加法操作换为减法操作,同时需要加一步比较的操作,因为我们在将两个数相减时肯定是用大的减去小的。
2.(1)
bool cmpstr(string s1,string s2){
if(s1.size()!=s2.size()) return s1.size()>=s2.size();
else return s1>=s2;
}
首先,s1.size()!=s2.size()
用来判断两个字符串的长度是否一致,若长度不同,就返回 s1.size()>=s2.size()
的结果。若 s1
的长度大于等于 s2
的长度,返回 true
;反之则返回 false
。
然后,若两个字符串长度相同,就执行 else
分支,s1>=s2
是按照字典序比较两个字符串。在 C++ 里,string
类型重载了比较运算符,>=
会按字典序判断 s1
是否大于等于 s2
。若 s1
在字典序上大于等于 s2
,返回 true
;反之则返回 false
。
之后进行调换操作
if(cmpstr(s1,s2)==false){
swap(s1,s2);
cout<<"-";
}
如果返回的是false,我们就进行调换,让s1-s2,同时让s1始终保持为较大的一个数
3. int lc = max(la,lb);
当两个数相减时,得到的最大位数与当前最大位数一样。
4.
for(int i=1;i<=lc;i++){
if(a[i] a[i+1]-=1;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
进行错位相减,然后去零,反向输出 。
#include
using namespace std;
string s1,s2;
int c[200],a[101],b[101];
void strtoint(string s,int a[]){
for(int i=0;i>s1>>s2;
int la = s1.size(),lb = s2.size();
strtoint(s1,a);
strtoint(s2,b);
int lc = la+lb;
for(int i=1;i<=la;i++){
for(int j=1;j<=lb;j++){
c[i+j-1] += a[i]*b[j];
c[i+j]+=c[i+j-1]/10;
c[i+j-1]%=10;
}
}
while(c[lc]==0&&lc>1) lc--;
for(int i=lc;i>0;i--){
cout<
1.首先整个流程与上两题类似
2.
lc = la+lb;
两数相乘,所得位数最大为两个位数相加
3.
for(int i=1;i<=la;i++){
for(int j=1;j<=lb;j++){
c[i+j-1] += a[i]*b[j];
c[i+j]+=c[i+j-1]/10;
c[i+j-1]%=10;
}
}
这里我们用到两个for循环进行相乘, c[i+j-1] += a[i]*b[j];这一步将两个具体位数相乘加上位数并放到合适的位数上,c[i+j]+=c[i+j-1]/10;这一步是给下一位增加进位,c[i+j-1]%=10;最后这一步是将两数相乘的结果的个位留下来。这里注意,前两步都是+=,是为了处理累加导致的进位,其实两个数相乘就是两个数相加。
4.去零,取反输出。
#include
using namespace std;
string s;
int a[100],c[100];
long long b;//低精度
int tmp;
void strtoint(string s,int a[]){
for(int i=0;i>s;
cin>>b;
int la = s.size();
strtoint(s,a);
for(int i=1;i<=la;i++){
c[i]=(tmp*10+a[i])/b;
tmp = (tmp*10+a[i])%b;
}
int lc=1;
while(c[lc]==0&&lc
1.这里我们将字符串变整型时,不需要取反,因为除法的运算规则就是从左到右实现的
2.
int lc=1;
while(c[lc]==0&&lc
这里在位数设置上,本质上最大位数是与高精度的那个数的位数相同,如果有零的情况,我们就去掉。
3.
for(int i=1;i<=la;i++){
c[i]=(tmp*10+a[i])/b;
tmp = (tmp*10+a[i])%b;
}
tmp * 10 + a[i]
:
在模拟大整数除法时,每次处理大整数 a
的一位数字 a[i]
。tmp
存储的是上一步计算得到的余数,将其乘以 10
再加上当前位数字 a[i]
,这样做是为了把上一步的余数和当前位数字组合起来,形成一个新的临时被除数。
(tmp * 10 + a[i]) / b
:
用新的临时被除数除以除数 b
,得到的商就是当前位的计算结果,将其存储到 c[i]
中。
(tmp * 10 + a[i]) % b
:
用新的临时被除数除以除数 b
后,取模运算得到的余数就是下一步计算要用到的余数,将其赋值给 tmp
,以便在处理下一位数字时使用。