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;
}
相关推荐
05候补工程师2 小时前
【线性代数笔记】初等变换、正交化与特殊矩阵性质核心总结
经验分享·笔记·线性代数·考研·矩阵
如君愿4 小时前
考研复习 Day 34 | 习题--计算机网络 第六章(应用层 下)、数据结构 查找算法(下)
数据结构·计算机网络·考研·课后习题
王老师青少年编程16 小时前
csp信奥赛C++高频考点专项训练之字符串 --【子串查找】:[NOIP 2009 提高组] 潜伏者
c++·字符串·csp·高频考点·信奥赛·子串查找·潜伏者
O&REO1 天前
哈工大网安 / 信安 837 考研复试机试&面试重点 + 资料汇总
考研·面试·职场和发展
王老师青少年编程1 天前
csp信奥赛C++高频考点专项训练之字符串 --【字符串排序】:生日
c++·字符串·csp·高频考点·信奥赛·生日·字符串排序
博界IT精灵1 天前
图的遍历(哈喜老师)
数据结构·考研·算法·深度优先
05候补工程师1 天前
【线性代数】考研复习万字长文:从“工厂模型”到矩阵变换,重构线代底层逻辑
线性代数·考研·矩阵·重构
如君愿1 天前
考研复习 Day 33 | 习题--计算机网络 第六章(应用层 上)、数据结构 查找算法(上)
数据结构·计算机网络·考研·课后习题
CS创新实验室2 天前
考研408全面指南:计算机学科专业基础综合考试深度解析
考研·计算机·408
GISer_Jing2 天前
考研|考公GIS:近5年地理信息产业数据全链路核心要点(背诵版)
学习·考研·arcgis