PKUKY150 浮点数加法
⭐️难度:简单
⭐️类型:字符串,基础数学
📖题目:题目链接

示例1
输入:
0.111111111111111111111111111111
0.111111111111111111111111111111
输出:
0.222222222222222222222222222222
🌟思路:
高精度浮点数运算,已经超过了int、double的要求,
可以把浮点数存储为字符串,自己设计关于浮点数的运算。
要解决的问题:
1️⃣对齐 小数点位置
2️⃣小数运算
3️⃣整数运算
加法的特点:(a+b+进位)% 10

⭕️设计小数加法时要注意:
1️⃣数组元素类型是字符,计算结果要-'0';
2️⃣如果相加结果大于9,计算结果要-10;
3️⃣计算式子要加上一位的进位;
总结得出:
cpp
for (int i = size - 1;i >= 0;i--) {
if (fa[i] + fb[i] + carry - '0' > '9') { // 有进位,例如:'2'+'9'-'0'= 11,保留个位:11-10=1
res[i] = fa[i] + fb[i] + carry - '0' - 10;
carry = 1;
}
else { // 无进位
res[i] = fa[i] + fb[i] + carry - '0';
carry = 0;
}
}
⭕️设计整数加法时要注意:
1️⃣整数部分长度不一致的话,长的部分直接照抄;
2️⃣如果进位为1的话,还是要继续算,不能退出循环;
总结得出:
cpp
for (int i = ia.size() - 1, j = ib.size() - 1;
i >= 0 || j >= 0 || carry == 1; // a整数 和 b整数 只要一方没算完,循环不能退出
i--, j--) {
if (i >= 0 && j >= 0) { // a 和 b 都还有数
if (ia[i] + ib[j] + carry - '0' > '9') {
res.insert(res.begin(), ia[i] + ib[j] + carry - '0' - 10); // 从开头开始插入
carry = 1;
}
else {
res.insert(res.begin(), ia[i] + ib[j] + carry - '0');
carry = 0;
}
}
else if (i >= 0 && j < 0) { // a还有数,b默认剩下全是0
if (ia[i] + carry > '9') {
res.insert(res.begin(), ia[i] + carry - 10);
carry = 1;
}
else {
res.insert(res.begin(), ia[i] + carry);
carry = 0;
}
}
else if (j >= 0 && i < 0) { // b还有数,a默认剩下全是0
if (ib[j] + carry > '9') {
res.insert(res.begin(), ib[j] + carry - 10);
carry = 1;
}
else {
res.insert(res.begin(), ib[j] + carry);
carry = 0;
}
}
else { // a 和 b 都算完了,只剩进位
res.insert(res.begin(), '1');
carry = 0;
}
}
📚题解:
cpp
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<vector> // vector不需要.h
#include<list>
#include<set> // // 可以用 set 和 multiset
#include<unordered_set> // 可以用 unordered_set 和 unordered_multiset
#include<map> // 可以用 map 和 multimap
#include<unordered_map> // 可以用 unordered_map 和 unordered_multimap
#include<algorithm>
#include<string>
#include<iostream>
#include<queue>
#include<stack>
using namespace std;
// 提取整数部分
string GetInteger(string a) {
return a.substr(0, a.find('.'));
}
// 提取小数部分
string GetFraction(string a) {
return a.substr(a.find('.') + 1, a.size() - a.find('.'));
}
// 计算小数加法:2件事:结果 和 进位
// 使用引用参数返回信息
void FractionPlus(string& res, int& carry, string fa, string fb) {
// 较短的小数后面补0
int size = max(fa.size(), fb.size());
while (fa.size() < size) {
fa.push_back('0');
}
while (fb.size() < size) {
fb.push_back('0');
}
res.resize(size); // 给res申请内存空间
carry = 0;
for (int i = size - 1; i >= 0; i--) {
if (fa[i] + fb[i] + carry - '0' >
'9') { // 有进位,例如:'2'+'9'-'0'= 11,保留个位:11-10=1
res[i] = fa[i] + fb[i] + carry - '0' - 10;
carry = 1;
} else { // 无进位
res[i] = fa[i] + fb[i] + carry - '0';
carry = 0;
}
}
return;
}
// 计算整数加法
void IntegerPlus(string& res, int carry, string ia, string ib) {
res.clear();
for (int i = ia.size() - 1, j = ib.size() - 1;
i >= 0 || j >= 0 ||
carry == 1; // a整数 和 b整数 只要一方没算完,循环不能退出
i--, j--) {
if (i >= 0 && j >= 0) { // a 和 b 都还有数
if (ia[i] + ib[j] + carry - '0' > '9') {
res.insert(res.begin(), ia[i] + ib[j] + carry - '0' -
10); // 从开头开始插入
carry = 1;
} else {
res.insert(res.begin(), ia[i] + ib[j] + carry - '0');
carry = 0;
}
} else if (i >= 0 && j < 0) { // a还有数,b默认剩下全是0
if (ia[i] + carry > '9') {
res.insert(res.begin(), ia[i] + carry - 10);
carry = 1;
} else {
res.insert(res.begin(), ia[i] + carry);
carry = 0;
}
} else if (j >= 0 && i < 0) { // b还有数,a默认剩下全是0
if (ib[j] + carry > '9') {
res.insert(res.begin(), ib[j] + carry - 10);
carry = 1;
} else {
res.insert(res.begin(), ib[j] + carry);
carry = 0;
}
} else { // a 和 b 都算完了,只剩进位
res.insert(res.begin(), '1');
carry = 0;
}
}
return;
}
int main() {
char arra[1000] = { 0 };
char arrb[1000] = { 0 };
while (scanf("%s%s", arra, arrb) != EOF) {
string a = arra;
string b = arrb;
string ia = GetInteger(a);
string ib = GetInteger(b);
string fa = GetFraction(a);
string fb = GetFraction(b);
int carry;
string fres;
FractionPlus(fres, carry, fa, fb);
string ires;
IntegerPlus(ires, carry, ia, ib);
printf("%s.%s\n", ires.c_str(), fres.c_str());
}
return 0;
}