题解
两个小数相加
1 条题解
-
0
解题思路
两个小数总长度不超过 25,不能直接当
double算(会丢失精度),要用高精度把每一位分开处理。因为两个数小数点后的位数相同,可以把整数部分和小数部分分别相加:- 整数部分:从个位往前逐位相加、处理进位。
- 小数部分:从最后一位往前逐位相加,多出来的进位加到整数部分的最低位。
- 最后拼起来:整数部分 +
.+ 小数部分。
要注意:输入的数字可能没有小数点(例如
34),这时小数位数是 0,输出也不用带小数点;整数部分相加时,两个数整数部分长度可能不同,短的按 0 补。参考代码
#include <iostream> using namespace std; char sa[30], sb[30]; int ansInt[35]; // 整数部分相加结果 int ansDec[30]; // 小数部分相加结果 int main() { cin >> sa >> sb; // 找到小数点位置(没有小数点就停在字符串结尾) int pa = 0, pb = 0; while (sa[pa] && sa[pa] != '.') pa++; while (sb[pb] && sb[pb] != '.') pb++; // 小数部分位数(两个数相同) int dl = 0; if (sa[pa] == '.') { while (sa[pa + 1 + dl]) dl++; } // 整数部分相加:两个数整数部分长度可能不同,短的按0算 int maxLen = (pa > pb) ? pa : pb; for (int i = 0; i < maxLen; i++) { int x = (i < pa) ? (sa[pa - 1 - i] - '0') : 0; int y = (i < pb) ? (sb[pb - 1 - i] - '0') : 0; ansInt[i] += x + y; ansInt[i + 1] += ansInt[i] / 10; // 进位 ansInt[i] %= 10; } // 小数部分从最后一位往前加 int carry = 0; for (int i = dl - 1; i >= 0; i--) { int s = (sa[pa + 1 + i] - '0') + (sb[pb + 1 + i] - '0') + carry; ansDec[i] = s % 10; carry = s / 10; } // 小数部分多出来的进位加到整数最低位 ansInt[0] += carry; int idx = 0; while (ansInt[idx] >= 10) { ansInt[idx + 1] += ansInt[idx] / 10; ansInt[idx] %= 10; idx++; } // 输出整数部分(去掉开头的0) int hi = maxLen; while (ansInt[hi]) hi++; int st = hi - 1; while (st > 0 && ansInt[st] == 0) st--; for (int i = st; i >= 0; i--) cout << ansInt[i]; // 输出小数点和每一位小数(没有小数部分就不输出点) if (dl > 0) { cout << "."; for (int i = 0; i < dl; i++) cout << ansDec[i]; } return 0; }复杂度分析
设两个数的长度为 n,整数、小数部分各扫一遍,时间复杂度 O(n);额外空间复杂度 O(n)。
- 1