51nod1005大數加法(C語言實現大數)
阿新 • • 發佈:2018-12-12
大數相加
基本思路是:
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陣列
程式碼和詳細註釋:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> using namespace std; const int maxn=1e4+7; char a[maxn],b[maxn],c[maxn]; int x[maxn],y[maxn]; void add(char a[],char b[]){ 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(){ gets(a); gets(b); add(a,b); return 0; }