PKUKY150 浮点数加法(北京大学考研机试真题)

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;
}
相关推荐
元亓亓亓7 小时前
考研408--数据结构--day11--最小生成树&最短路径问题&拓扑排序&关键路径
数据结构·考研·最小生成树·拓扑排序·最短路径·关键路径
码农幻想梦3 天前
3555. 二叉树(北京邮电大学考研机试题)
考研·
元亓亓亓3 天前
考研408--数据结构--day10--图的存储、基本操作和遍历
数据结构·考研·
远方2354 天前
哈希计算器1.0
字符串·md5·哈希·sha256
元亓亓亓4 天前
考研408--数据结构--day9--树(存储结构)、森林(遍历)与二叉树的转换&哈夫曼树&并查集
数据结构·考研
小优整合4 天前
2026冲刺季:考研失利如何快速转型求职
考研·求职招聘
hnjzsyjyj6 天前
洛谷 P13270:【模板】最小表示法 ← 双指针 + 解环成链
字符串·双指针·解环成链
会叫的恐龙7 天前
C++ 核心知识点汇总(第六日)(字符串)
c++·算法·字符串