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;
}
相关推荐
Thomas.Sir1 小时前
第三章:Python3 之 字符串
开发语言·python·字符串·string
马士兵教育14 小时前
AI大模型教程【LangChainV1.0+LangGraph V1.0】企业级Agent全集开发实战!
开发语言·人工智能·考研·面试·职场和发展
西电研梦1 天前
西电26考研复录比、26VS25考研录取人数变化
大数据·考研·研究生·西安电子科技大学
haaaaaaarry2 天前
【操作系统】第三章 内存管理(一)
linux·考研·操作系统
毕设源码-钟学长2 天前
【开题答辩全过程】以 考研信息共享交流系统的设计与实现为例,包含答辩的问题和答案
考研
优化控制仿真模型3 天前
【英二】考研英语二历年真题及答案解析PDF电子版(1980-2025年)
经验分享·考研·pdf
其实秋天的枫3 天前
【英一】考研英语一历年真题及答案解析PDF电子版(1980-2025年)
考研·pdf
西电研梦3 天前
西电26考研初/复试分数占比、笔试、面试斩杀线
考研·面试·职场和发展·研究生·西安电子科技大学
其实秋天的枫3 天前
【英二】考研英语二历年真题及答案解析PDF电子版(1980-2025年)
考研·pdf
要努力点3 天前
26考研——计算机考研复试——0854(2)
java·c语言·考研·算法·复试