大数相加
基本思路是:
1、两个字符串把大数读进来 然后把每一位字符换成数字存到 x y 数组里面
2、拿 x y 数组从后往前 对应位相加 (注意进位) 相加的结果依次存到 c数组里
3、然后对c数组处理
如果最高位小于0 那么结果肯定是负数 就打印一个负号 然后把每一位数字变成正数
如果最高位大于0 就不用变
但是这里有特殊情况 负数+正数 最高位是正的 其他位有负的的情况
比如 1000 + -1 按位加得到的是 (1 0 0 -1)
344 + -155 按位加得到的是 (2 -1 -1)
解决方法是 低位是负数的地方 就向前一位借 1
4、输出c数组 输出要去掉前导0 这时候 要注意 0+0 -1+1 这些结果本来就是0的情况要特殊处理
测试数据: ( 1000 , -1 ) ( 0 , 0)
代码和详细注释:
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn=1e4+7;
char a[maxn],b[maxn];
int x[maxn],y[maxn],c[maxn];
void add(){
int l1=strlen(a);
int l2=strlen(b);
//处理两个大数 如果是负数 就每一位都变成负的
//将处理好的数字 放到x数组的 1-l1 和y数组的 1-l2上(空出0的位置)
//处理完了后 l1 l2 代表的就是数字的位数
//1
if(a[0]=='-'){
for(int i=1;i<l1;i++)x[i]=-(a[i]-'0');
l1--;
}
else{
for(int i=0;i<l1;i++)x[i+1]=a[i]-'0';
}
//2
if(b[0]=='-'){
for(int i=1;i<l2;i++)y[i]=-(b[i]-'0');
l2--;
}
else{
for(int i=0;i<l2;i++)y[i+1]=b[i]-'0';
}
//x 和 y从后开始按位相加存到c数组里
//flag代表进位 c数组长度w是l1 l2中较大的那个
int flag=0,w=max(l1,l2);
for(int i=l1,j=l2;1;i--,j--){
if(i<1)x[i]=0;
if(j<1)y[j]=0;
if(w==0){//w减到0 判断还有没有进位
c[w]=flag;break;
}
if(x[i]+y[j]+flag>0){
if(x[i]+y[j]+flag>9){
c[w--]=x[i]+y[j]+flag-10; flag=1;
}
else {
c[w--]=x[i]+y[j]+flag; flag=0;
}
}
else{
if(x[i]+y[j]+flag<-9){
c[w--]=x[i]+y[j]+flag+10; flag=-1;
}
else{
c[w--]=x[i]+y[j]+flag; flag=0;
}
}
}
//空出来的0号位置就是来存放最高位的进位的
//如果最高位没有进位 那就要从1开始 答案在s和len之间
int s=0,len=max(l1,l2);
if(c[s]==0)s++;
//如果最高位小于0 那结果肯定是负 输出负号 把其他位上数字都变为正数
if(c[s]<0){
printf("-");for(int i=s;i<=len;i++)c[i]=-c[i];
}
// 还存在 特殊情况(100 + -1)(100 + -23)(1000 + -999)
//比如 100 + -1 对应位相加 得到的是 1 0 -1 最高位大于0 其他却有负的
//这个时候 需要从最低位依次向前借1
for(int i=len;i>=s;i--){
if(c[i]<0){
c[i]+=10;c[i-1]--;
}
}
//0 + 0 1 + -1 答案是0 后面要进行去掉前导0的操作 这里要特殊处理
if(s==len&&c[s]==0)printf("0");
//去掉前导0 从s输出到len
flag=0;
for(int i=s;i<=len;i++){
if(c[i]!=0)flag=1;
if(flag==1)printf("%d",c[i]);
}
printf("\n");
}
int main(){
scanf("%s",a);
scanf("%s",b);
add();
return 0;
}