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;
}
相关推荐
imbackneverdie20 小时前
科研绘图踩坑多年,我总结出了零设计基础出期刊级插图的方法
人工智能·考研·ai·信息可视化·ai作画·科研绘图·研究生
我是无敌小恐龙1 天前
线下班第一课
python·考研·django·ai编程
codebrick1 天前
408 数据结构:快排 / 堆排 / 归并 / 希尔 等排序算法对比(复杂度、稳定性、真题考点
数据结构·考研·算法·排序算法·408
MaCa .BaKa1 天前
52-考研备考服务平台系统-考研系统
java·spring boot·mysql·考研·tomcat·maven·mybatis
itman3013 天前
C语言printf输出格式:%d %f %s等用法详解
c语言·字符串·printf·格式化输出·整数
Tisfy3 天前
LeetCode 2515.到目标字符串的最短距离:从中间往两边遍历
算法·leetcode·字符串·题解·数组·遍历
庞轩px3 天前
第二篇:String、StringBuilder、StringBuffer深度剖析
java·字符串·stringbuilder·string·stringbuffer·字符串常量池
罗湖老棍子4 天前
Power Strings(信息学奥赛一本通- P1457)
算法·字符串·哈希
酉鬼女又兒5 天前
零基础快速入门计算机组成原理:《DRAM 刷新方式小结 & SRAM/DRAM 优劣及主存缓存划分》
考研·职场和发展·电脑·计算机组成原理
做cv的小昊5 天前
【TJU】研究生应用统计学课程笔记(1)——第一章 数理统计的基本知识(1.1 数理统计的基本内容、1.2 数理统计的基本概念)
笔记·线性代数·考研·数学建模·ai·矩阵·概率论