大数加法(C++实现)

最常规的大数加法 (两个数都是非负的整数)

 

思路:

用字符串的方式去存储我们需要计算的数 ,但是要注意的一点就是我们是倒过来存储这个大数的

比如: 123456789 我们存储的时候是存成  987654321

为什么要这么干? 我觉得是为了便于后面我们的进位操作吧 

 

最常规的大数加法 (两个数都是非负的整数)

 1 #include<iostream>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int L=110;
 6 string add(string a,string b)//只限两个非负整数相加
 7 {
 8     string ans;
 9     int na[L]={0},nb[L]={0};
10     int la=a.size();
11     int lb=b.size();
12     // 倒叙存储
13     for(int i=0;i<la;i++)
14         na[la-1-i]=a[i]-'0';
15     // 倒叙存储
16     for(int i=0;i<lb;i++) 
17         nb[lb-1-i]=b[i]-'0';
18     int lmax=la>lb?la:lb;
19     // 从个位开始计算
20     for(int i=0;i<lmax;i++) 
21     {
22         na[i]+=nb[i];
23         na[i+1]+=na[i]/10;
24         na[i]%=10;
25     }
26     // 去除前置0
27     if(!na[lmax]) 
28         lmax--;  
29     for(int i=lmax;i>=0;i--) 
30         ans+=na[i]+'0';
31     return ans;
32 }
33 int main()
34 {
35     string a,b;
36     while(cin>>a>>b)
37         cout<<add(a,b)<<endl;
38     return 0;
39 }

 

【变形一】 正负整数的大数的加法

 

思路:

大体的思路和常规的大数加法还是一样的,唯一不同的就是多了对最后结果的判断(是正数还是负数)

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #include <iostream>
  5 #include <cstring>
  6 
  7 using namespace std;
  8 
  9 const int maxn = 10010;
 10 
 11 char a[maxn],b[maxn];
 12 int aa[maxn],bb[maxn];
 13 
 14 
 15 void add(char str1[],char str2[])
 16 {
 17     memset(aa,0, sizeof(aa));
 18     memset(bb,0, sizeof(bb));
 19     int len1 = strlen(str1);
 20     int len2 = strlen(str2);
 21     int flag1 = 0,flag2 = 0;
 22     // 都是0的时候特殊处理
 23     if (str1[0] == '0' && str2[0] == '0')
 24         printf("0\n");
 25     else
 26     {
 27         // str1是负数
 28         if (str1[0] == '-')
 29         {
 30             flag1 = 1;
 31             for (int i=0;i<len1-1;i++)
 32             {
 33                 aa[i] = str1[len1-1-i] - '0'; //倒叙记录
 34             }
 35         }
 36         else
 37         {
 38             // str1是正数
 39             for (int i=0;i<len1;i++)
 40             {
 41                 aa[i] = str1[len1-1-i] -'0';
 42             }
 43         }
 44 
 45         //str2是负数
 46         if (str2[0] == '-')
 47         {
 48             flag2 = 1;
 49             for (int i=0;i<len2-1;i++)
 50             {
 51                 bb[i] = str2[len2-1-i] - '0';
 52             }
 53         }
 54         else
 55         {
 56             // str2是正数
 57             for (int i=0;i<len2;i++)
 58             {
 59                 bb[i] = str2[len2-1-i]- '0';
 60             }
 61         }
 62 
 63     //分四种情况对str1,str2处理
 64 
 65     if (!flag1 && !flag2) //str1 和 str2都是正数
 66     {
 67         int len = max(len1,len2);
 68         for (int i=0;i<len;i++)
 69         {
 70             bb[i] += aa[i];
 71             bb[i+1] += bb[i]/10;
 72             bb[i]%=10;
 73         }
 74         //处理前置零
 75         while (!bb[len])
 76             len--;
 77         for (;len>=0;len--)
 78             printf("%d",bb[len]);
 79         printf("\n");
 80     }
 81     else if (!flag1 && flag2) // str1是正数,str2是负数
 82     {
 83         int ans = 0;
 84         //判断str1和str2的绝对值谁大谁小
 85         if (len1>len2-1)
 86             ans = 1;
 87         else if (len1 == len2-1)
 88         {
 89             for (int i=len1-1;i>=0;i--)
 90             {
 91                 if (aa[i]>bb[i])
 92                 {
 93                     ans = 1;
 94                     break;
 95                 }
 96                 else if (aa[i]<bb[i])
 97                 {
 98                     ans = 0;
 99                     break;
100                 }
101             }
102         }
103         // 如果str1的绝对值更大
104         if (ans)
105         {
106             for (int i=0;i<len1;i++)
107             {
108                 aa[i] -= bb[i];
109                 while (aa[i]<0)
110                 {
111                     aa[i] += 10;
112                     aa[i+1]--;
113                 }
114             }
115             //处理前置零
116             while (!aa[len1])
117                 len1--;
118             for (;len1>=0;len1--)
119                 printf("%d",aa[len1]);
120             printf("\n");
121         }
122         else  // 如果str2的绝对值更大
123         {
124             for (int i=0;i<len2-1;i++)
125             {
126                 bb[i] -= aa[i];
127                 while (bb[i]<0)
128                 {
129                     bb[i]+=10;
130                     bb[i+1]--;
131                 }
132             }
133             //处理前置零
134             while (!bb[len2])
135                 len2--;
136             if (len2<0)    // 注意333  -333 的情况
137                 printf("0\n");
138             else
139             {
140                 for (;len2>=0;len2--)
141                     printf("%d",bb[len2]);
142                 printf("\n");
143             }
144         }
145     }
146     else if (flag1 && !flag2) //str1为负数 str2为正数
147     {
148         int ans = 0;
149         // 判断str1 和 str2 的绝对值的大小
150         if (len2>len1-1)
151         {
152             ans = 1;
153         }
154         else if (len2 == len1-1)
155         {
156             for (int i = len2 - 1; i >= 0; i--)
157             {
158                 if (aa[i] > bb[i])
159                 {
160                     ans = 0;
161                     break;
162                 }
163                 else if (bb[i] > aa[i])
164                 {
165                     ans = 1;
166                     break;
167                 }
168             }
169         }
170         //判断结果的正负
171         if (ans)
172         {
173             for (int i=0;i<len2;i++)
174             {
175                 bb[i] -= aa[i];
176                 while (bb[i]<0)
177                 {
178                     bb[i]+=10;
179                     bb[i+1]--;
180                 }
181             }
182             //处理前置0
183             while (!bb[len2])
184                 len2--;
185             for (;len2>=0;len2--)
186                 printf("%d",bb[len2]);
187             printf("\n");
188         }
189         else
190         {
191             for (int i=0;i<len1-1;i++)
192             {
193                 aa[i] -= bb[i];
194                 while (aa[i]<0)
195                 {
196                     aa[i]+=10;
197                     aa[i+1]--;
198                 }
199             }
200             //处理前置0
201             while (!aa[len1])
202                 len1--;
203             if (len1<0)        // 注意333 -333 的情况
204                 printf("0\n");
205             else
206             {
207                 printf("-");
208                 for (;len1>=0;len1--)
209                 {
210                     printf("%d",aa[len1]);
211                 }
212                 printf("\n");
213             }
214         }
215     }
216     else if (flag1 && flag2) // 都是负数
217     {
218         printf("-");
219         int len = max(len1,len2);
220         for (int i=0;i<len-1;i++)
221         {
222             bb[i] += aa[i];
223             bb[i+1] += bb[i]/10;
224             bb[i]%=10;
225         }
226         while (!bb[len])
227             len--;
228         for (;len>=0;len--)
229             printf("%d",bb[len]);
230         printf("\n");
231     }
232     }
233 }
234 
235 
236 
237 
238 
239 int main()
240 {
241     while (cin >> a >> b)
242     {
243         add(a,b);
244     }
245     return 0;
246 }

 

【变形二】正小数的大数加法

 

思路:我们把小数部分和整数部分分开来考虑

 

  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 #include <iostream>
  5 #include <cstring>
  6 
  7 using namespace std;
  8 
  9 int len,len1,len2,i,j,k,x1,x2,y1,y2,m,n;
 10 char str1[450],str2[450];
 11 int a1[450],a2[450],a3[450],b1[450],b2[450],b3[450],a[450],b[450],c[450];
 12 
 13 
 14 void add(char str1[],char str2[])
 15 {
 16     memset(a1,0, sizeof(a1));
 17     memset(a2,0, sizeof(a2));
 18     memset(a3,0, sizeof(a3));
 19     memset(b1,0, sizeof(b1));
 20     memset(b2,0, sizeof(b2));
 21     memset(b3,0, sizeof(b3));
 22     memset(a,0, sizeof(a));
 23     memset(b,0, sizeof(b));
 24     memset(c,0, sizeof(c));
 25     len1 = strlen(str1);
 26     len2 = strlen(str2);
 27     //找到str1小数点
 28     for (i=0;i<len1;i++)
 29     {
 30         if (str1[i] == '.')
 31             break;
 32     }
 33     //存储str1小数部分
 34     for (k=len1-1,j=0;k>i;k--,j++)
 35     {
 36         a1[j] = str1[k] -'0';
 37     }
 38     x1 = j; //记录a1的长度(小数部分)
 39     i = i - 1;
 40     //存储str2整数部分
 41     for (j=0;i>=0;i--,j++)
 42     {
 43         a2[j] = str1[i] - '0';
 44     }
 45     x2 = j; //记录a2数组的长度(整数部分)
 46 
 47     //找到str1的小数点
 48     for (i=0;i<len2;i++)
 49     {
 50         if (str2[i] == '.')
 51             break;
 52     }
 53     //存储str2小数部分
 54     for (k=len2-1,j=0;k>i;k--,j++)
 55     {
 56         b1[j] = str2[k]-'0';
 57     }
 58     y1 = j; //记录b1的长度(str2的小数部分)
 59     i = i - 1;
 60     // 存储str2的整数部分
 61     for (j=0;i>=0;i--,j++)
 62     {
 63         b2[j] = str2[i] - '0';
 64     }
 65     y2 = j; //记录b2的长度(str2的整数部分)
 66 
 67     // 对齐小数部分
 68     if (x1<=y1)
 69     {
 70         m = y1 - x1;
 71         n = y1;
 72         for (i = 0; i < x1; i++)
 73         {
 74             a3[i + m] = a1[i];
 75         }
 76         for (i = 0; i < y1; i++)
 77         {
 78             b3[i] = b1[i];
 79         }
 80     }
 81     else
 82     {
 83         m = x1 - y1;
 84         n = x1;
 85         for (i = 0; i < y1; i++)
 86         {
 87             b3[i+m] = b1[i];
 88         }
 89         for (i=0;i < x1;i++)
 90         {
 91             a3[i] = a1[i];
 92         }
 93     }
 94 
 95     //计算小数部分
 96     for (i=0;i<n;i++)
 97     {
 98         b[i] += a3[i]+b3[i];
 99         b[i+1] += b[i]/10;
100         b[i] = b[i]%10;
101     }
102     //第一位的小数需要进位
103     if (b[n] == 1)
104     {
105         a2[0]+=1;
106         b[n]=0;
107     }
108 
109     //计算整数部分
110     if (x2>=y2)
111         m=x2;
112     else
113         m=y2;
114     for (i=0;i<m;i++)
115     {
116         a[i]+=b2[i]+a2[i];
117         a[i+1]+=a[i]/10;
118         a[i]%=10;
119     }
120 
121     //处理整数的前置0
122     for (i=m+5;i>=0&&a[i]==0;i--)
123     {
124          ;
125     }
126     //存在不为0的部分
127     if (i>=0)
128     {
129         for (;i>=0;i--)
130             printf("%d",a[i]);
131     }
132     else //整数部分是0
133     {
134         printf("0");
135     }
136 
137     //处理小数的后置0
138     k = 0;
139     for (k=0;k<n&&b[k]==0;k++)
140     {
141         ;
142     }
143     //如果第n-1个还是0,那么则说明小数部分不存在
144     if (k!=n)
145     {
146         printf(".");
147         for (int i=n-1;i>=k;i--)
148         {
149             printf("%d",b[i]);
150         }
151     }
152     printf("\n");
153 }
154 
155 
156 
157 
158 
159 int main()
160 {
161     while (cin >> str1 >> str2)
162     {
163         add(str1,str2);
164     }
165     return 0;
166 }

 

posted @ 2019-07-15 21:13  _Ackerman  阅读(11576)  评论(3编辑  收藏  举报