新人,第一次写,可能会出现各种错误,望各位多多指教。 洛谷1601 题目描述 高精度加法,相当于 a+b problem,不用考虑负数。 输入格式 分两行输入。a,b≤10的500次方。 输出格式 输出只有一行,代表a+b 的值
a+b问题一直以来都被视为最为简单的初学者题目之一。但是,当a+b的数值过大,超过了long long的最大范围时,我们又该如何处理a+b问题呢?本章将对其进行探讨与讲解。
首先,我们很容易想到用字符数组进行读入,读入函数如下:
#include<bits/stdc++.h>
using namespace std;
char a[505],b[505];
void read(){
scanf("%s",a+1);
scanf("%s",b+1);
}
然后,我们要考虑如何进行两个字符数组的加法运算。
显然,我们还需要还需要开int类型的数组对字符数组中各个数位上的数进行储存,对代码进行增添后如下:
#include<bits/stdc++.h>
using namespace std;
char a[505],b[505];
int lena,lenb;
int aint[505],bint[505];//开int数组
void read(){
scanf("%s",a+1);
lena=strlen(a+1);//strlen函数记录字符长度
scanf("%s",b+1);
lenb=strlen(b+1);//
for(int i=1;i<=lena;i++){
aint[i]=a[i]-48;//-48是为了将字符转变为数字。在ACII码中,1对应49;
}
for(int i=1;i<=lenb;i++){
bint[i]=b[i]-48;
}
}//read函数定义完毕
至此,a和b两个数均由int数组从高位向低位存储。
我们开始正式进行加法运算,先开一个int类型的数组对a+b的和的各个数位对应的数进行存储:
#include<bits/stdc++.h>
using namespace std;
char a[505],b[505];
int lena,lenb;
int aint[505],bint[505];//开int数组
void read(){
scanf("%s",a+1);
lena=strlen(a+1);//strlen函数记录字符长度
scanf("%s",b+1);
lenb=strlen(b+1);//
for(int i=1;i<=lena;i++){
aint[i]=a[i]-48;//-48是为了将字符转变为数字。在ACII码中,1对应49;
}
for(int i=1;i<=lenb;i++){
bint[i]=b[i]-48;
}
}//read函数定义完毕
int cint[505];
由于竖式运算中,我们是从低位开始算起的,满十进一,所以我们进行竖式加法运算时要倒序着加。新定义一个add函数:
#include<bits/stdc++.h>
using namespace std;
char a[505],b[505];
int lena,lenb;
int aint[505],bint[505];//开int数组
void read(){
scanf("%s",a+1);
lena=strlen(a+1);//strlen函数记录字符长度
scanf("%s",b+1);
lenb=strlen(b+1);//
for(int i=1;i<=lena;i++){
aint[i]=a[i]-48;//-48是为了将字符转变为数字。在ACII码中,1对应49;
}
for(int i=1;i<=lenb;i++){
bint[i]=b[i]-48;
}
}//read函数定义完毕
int cint[505];
void add(){
int x;//x用来满十进一看留多少
int lenc=lenb;//lenc用来记录和的长度
if(lena>lenb)lenc=lena;
else lenc=lenb;
for(int i=lenc;i>=1;i--){
cint[i]=
}
}
准备从个位开始a+b时突然出现了问题。lena与lenb不一定相等,所以需要对前面的程序进行修改。改成从低位向高位储存数字。
#include<bits/stdc++.h>
using namespace std;
char a[505],b[505];
int lena,lenb;
int aint[505],bint[505];//开int数组
void read(){
scanf("%s",a+1);
lena=strlen(a+1);//strlen函数记录字符长度
scanf("%s",b+1);
lenb=strlen(b+1);//
for(int i=lena;i>=1;i--){
aint[i]=a[lena-i+1]-48;//-48是为了将字符转变为数字。在ACII码中,1对应49;
}
for(int i=lenb;i>=1;i--){
bint[i]=b[lenb-i+1]-48;//注意从低位向高位储存,否则后面的运算会出现问题。
}
}//read函数定义完毕
int cint[505];
int lenc=lenb;//lenc用来记录和的长度
void add(){
int x=0;//x用来满十进一看留多少
if(lena>lenb)lenc=lena;
else lenc=lenb;
for(int i=1;i<=lenc;i++){//从低位开始a+b;
if((aint[i]+bint[i]+x)<10){
cint[i]=aint[i]+bint[i]+x;
x=0;
continue;
}
if((aint[i]+bint[i]+x)>=10){
cint[i]=(aint[i]+bint[i]+x)%10;
x=1;
continue;}//考虑是否进位;
if(i==lenc&&(aint[i]+bint[i]+x)>=10){
lenc++;
cint[lenc]=1;
break;//考虑加到最高位的特殊情况
}
}
}//加完了!!!
最后就很简单了。
#include<bits/stdc++.h>
using namespace std;
char a[505],b[505];
int lena,lenb;
int aint[505],bint[505];//开int数组
void read(){
scanf("%s",a+1);
lena=strlen(a+1);//strlen函数记录字符长度
scanf("%s",b+1);
lenb=strlen(b+1);//
for(int i=lena;i>=1;i--){
aint[i]=a[lena-i+1]-48;//-48是为了将字符转变为数字。在ACII码中,1对应49;
}
for(int i=lenb;i>=1;i--){
bint[i]=b[lenb-i+1]-48;//注意从低位向高位储存,否则后面的运算会出现问题。
}
}//read函数定义完毕
int cint[505];
int lenc=lenb;//lenc用来记录和的长度
void add(){
int x=0;//x用来满十进一看留多少
if(lena>lenb)lenc=lena;
else lenc=lenb;
for(int i=1;i<=lenc;i++){//从低位开始a+b;
if((aint[i]+bint[i]+x)<10){
cint[i]=aint[i]+bint[i]+x;
x=0;
continue;
}
if((aint[i]+bint[i]+x)>=10){
cint[i]=(aint[i]+bint[i]+x)%10;
x=1;
continue;}//考虑是否进位;
if(i==lenc&&(aint[i]+bint[i]+x)>=10){
lenc++;
cint[lenc]=1;
break;//考虑加到最高位的特殊情况
}
}
}//加完了!!!
void print(){
for(int i=lenc;i>=1;i--){
printf("%d",cint[i]);//输出函数
}
}
int main(){
read();
add();
print();
return 0;//大功告成!
}
但是,问题又来了。
有一组测试结果是错误的。拿到测试数据后,我发现了问题所在。我们定义的add函数中对于最高位相加是否进一位的if判断语句应当提前,否则会收到continue语句的影响,导致出错。
对add函数中if语句的位置进行调整后·,完整代码如下:
#include<bits/stdc++.h>
using namespace std;
char a[505],b[505];
int lena,lenb;
int aint[505],bint[505];//开int数组
void read(){
scanf("%s",a+1);
lena=strlen(a+1);//strlen函数记录字符长度
scanf("%s",b+1);
lenb=strlen(b+1);//
for(int i=lena;i>=1;i--){
aint[i]=a[lena-i+1]-48;//-48是为了将字符转变为数字。在ACII码中,1对应49;
}
for(int i=lenb;i>=1;i--){
bint[i]=b[lenb-i+1]-48;//注意从低位向高位储存,否则后面的运算会出现问题。
}
}//read函数定义完毕
int cint[505];
int lenc=lenb;//lenc用来记录和的长度
void add(){
int x=0;//x用来满十进一看留多少
if(lena>lenb)lenc=lena;
else lenc=lenb;
for(int i=1;i<=lenc;i++){//从低位开始a+b;
if(i==lenc&&(aint[i]+bint[i]+x)>=10){
lenc++;
cint[lenc]=1;
break;//考虑加到最高位的特殊情况
}
if((aint[i]+bint[i]+x)<10){
cint[i]=aint[i]+bint[i]+x;
x=0;
continue;
}
if((aint[i]+bint[i]+x)>=10){
cint[i]=(aint[i]+bint[i]+x)%10;
x=1;
continue;}//考虑是否进位;
}
}//加完了!!!
void print(){
for(int i=lenc;i>=1;i--){
printf("%d",cint[i]);//输出函数
}
}
int main(){
read();
add();
print();
return 0;//大功告成!
}
改对了!
高精度减法与高精度加法大同小异,我们直接上代码
#include<bits/stdc++.h>
using namespace std;
char a[505],b[505];
int aint[505],bint[505],cint[505];
int lena,lenb,lenc;
void read(){
scanf("%s",a+1);
scanf("%s",b+1);
lena=strlen(a+1);
lenb=strlen(b+1);
for(int i=1;i<=lena;i++){
aint[i]=a[lena-i+1]-48;
}
for(int i=1;i<=lenb;i++){
bint[i]=b[lenb-i+1]-48;//从个位向最高位存储
}
}
void dec(){
if(lena>lenb||(lena==lenb&&strcmp(a+1,b+1)>=0)){
for(int i=1;i<=lena;i++){
if(aint[i]-bint[i]<0){
cint[i]=aint[i]-bint[i]+10;
aint[i+1]--;
}
else cint[i]=aint[i]-bint[i];
}
}
if(lena<lenb||(lena==lenb&&strcmp(a+1,b+1)<0)){
lenc=lenb;
for(int i=1;i<=lenc;i++){
if(bint[i]-aint[i]<0){
cint[i]=bint[i]-aint[i]+10;
bint[i+1]--;
}
else cint[i]=bint[i]-aint[i];
}
while(cint[lenc]==0){
lenc--;}
}
}
void print(){
if(lena>lenb||(lena==lenb&&strcmp(a+1,b+1)>=0)){
for(int i=lena;i>=1;i--){
printf("%d",cint[i]);
}
}
if(lena<lenb||(lena==lenb&&strcmp(a+1,b+1)<0)) {
printf("-");
for(int i=lenc;i>=1;i--){
printf("%d",cint[i]);}
}
}
int main(){
read();
dec();
print();
return 0;
}
不过,需要注意的是strcmp函数的应用(比较字符串大小)以及前导0的去除。