大数加法(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 }