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;
}
相关推荐
酉鬼女又兒5 天前
零基础入门计算机网络运输层:端到端通信核心作用、端口号分类规则、复用分用工作机制及UDP与TCP协议全方位对比详解
网络·网络协议·tcp/ip·计算机网络·考研·udp·php
小马哥crazymxm6 天前
Arxiv论文周选 (2026-W24)
论文阅读·人工智能·考研
酉鬼女又兒7 天前
零基础入门计算机网络网际层核心:IP数据报发送与转发完整流程、静态路由配置方法、路由环路成因与解决方案及历年考研经典例题深度解析
网络·tcp/ip·计算机网络·考研·职场和发展
Tisfy7 天前
LeetCode 3838.带权单词映射:求和、取模、拼接(附python一行版)
python·算法·leetcode·字符串·题解·模拟·取模
酉鬼女又兒7 天前
零基础入门IPv4地址:从基本概念、分类编址、子网划分到无分类编址与应用规划全解
网络·网络协议·计算机网络·考研·职场和发展·分类·智能路由器
killerbasd8 天前
总结 6.13
考研
05候补工程师9 天前
【408考研复习】数据结构核心笔记:字符串模式匹配与内部排序算法全解析
数据结构·经验分享·笔记·考研·算法·排序算法
乘~风10 天前
408考研-计组-1.2计算机系统层次结构笔记+1.3计算机性能指标
笔记·考研·408
killerbasd10 天前
总结 6.11
考研
唐维康10 天前
F00403综合程序设计考什么?昆工891复试全流程拆解
考研