当前位置:首页 > 洛谷 > 洛谷P1572题解析:分数计算的优化解法与代码实现

洛谷P1572题解析:分数计算的优化解法与代码实现

3小时前

洛谷P1572题解析:分数计算的优化解法与代码实现 洛谷题解 C++ GCD算法 字符串 第1张

一、题目解读

洛谷P1572题要求处理包含分数与运算符的输入表达式,计算并输出最简分数结果。题目难点在于:

1)解析混合的分数与整数表达式;

2)分数化简至最简形式;

3)处理连续加减运算。

需结合数学算法与编程逻辑,实现高效计算。

二、解题思路

1. 模块化设计:定义分数结构体(分子、分母),封装化简与加法函数,提升代码复用性。

2. GCD优化:利用辗转相除法求最大公约数,简化分数至最简形式(避免分母为负数)。

3. 输入解析:通过循环遍历字符,分离符号、分子、分母,整数视为分母为1的特殊分数。

4. 运算处理:按运算符顺序累加分数,每次加法后调用化简函数,减少重复计算。

三、解题步骤

1. 读取输入:使用getline获取整行表达式,避免空格干扰。

2. 数值分离:

○ 识别符号(+/-),记录数值正负。

○ 提取分子:连续数字拼接成整数。

○ 若遇到'/',继续提取分母;否则默认分母为1。

3. 构建分数列表:将解析的分数存入vector,同时记录运算符。

4. 循环计算:

○ 初始化结果分数为第一个分数。

○ 遍历后续分数与运算符,根据符号执行加法或减法(转化为加法与负数)。

○ 每次运算后调用simplify()化简。

5. 输出结果:最终分数化简后输出分子与分母。

四、代码与注释

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;

// 计算最大公约数(辗转相除法)
int gcd(int a, int b) {
    return b == 0? a : gcd(b, a % b); // 递归终止条件与迭代
}

// 分数结构体
struct Fraction {
    int numerator;   // 分子
    int denominator; // 分母

    // 化简分数:通过GCD去除公约数,确保分母为正
    void simplify() {
        int common = gcd(abs(numerator), abs(denominator));
        numerator /= common;
        denominator /= common;
        // 修正符号(分母始终为正)
        if (denominator < 0) {
            numerator *= -1;
            denominator *= -1;
        }
    }

    // 分数加法(核心运算)
    Fraction operator+(const Fraction& other) const {
        Fraction result;
        // 通分后相加:分子 = 分子1*分母2 + 分子2*分母1
        result.numerator = numerator * other.denominator + other.numerator * denominator;
        result.denominator = denominator * other.denominator;
        // 运算后立即化简
        result.simplify();
        return result;
    }
};

int main() {
    string s;
    getline(cin, s); // 输入整行表达式

    vector<Fraction> fractions; // 存储解析后的分数
    vector<char> operators;     // 存储运算符(+/-)

    // 解析输入:逐字符分离符号、分子、分母
    int i = 0;
    while (i < s.size()) {
        // 解析符号(可选)
        int sign = 1;
        if (s[i] == '-') {
            sign = -1; // 负数标记
            i++;
        } else if (s[i] == '+') {
            i++; // 跳过正号
        }

        // 解析分子(连续数字)
        int num = 0;
        while (i < s.size() && isdigit(s[i])) {
            num = num * 10 + (s[i] - '0'); // 字符转数字
            i++;
        }
        num *= sign; // 应用符号

        // 解析分母(存在'/'时)
        if (i < s.size() && s[i] == '/') {
            i++; // 跳过'/'
            int den = 0;
            while (i < s.size() && isdigit(s[i])) {
                den = den * 10 + (s[i] - '0');
                i++;
            }
            fractions.push_back({num, den}); // 存入分数
        } else {
            // 整数视为分母为1的分数
            fractions.push_back({num, 1});
        }

        // 记录运算符(后续处理)
        if (i < s.size() && (s[i] == '+' || s[i] == '-')) {
            operators.push_back(s[i]); // 存储符号
            i++; // 跳过运算符
        }
    }

    // 计算最终结果
    Fraction result = fractions[0]; // 初始化为第一个分数
    for (int j = 1; j < fractions.size(); j++) {
        // 根据运算符执行加法(减法转为加法负数)
        if (operators[j-1] == '-') {
            result = result + (-fractions[j]); // 负数分数
        } else {
            result = result + fractions[j];
        }
    }

   
     // 输出结果
    if (result.denominator == 1) {
        cout << result.numerator << endl;
    } else {
        cout << result.numerator << "/" << result.denominator << endl;
    }
    
    return 0;
}

五、总结

本文通过自定义分数结构体和GCD算法,实现了洛谷P1572题的简洁解法。核心在于将分数运算模块化,结合输入解析与符号处理,确保结果准确且符合最简要求。代码结构清晰,适用于算法学习与竞赛实践,同时通过关键词优化提升

原创内容 转载请注明出处

分享给朋友:

相关文章

力扣1221:一次扫描解决分割平衡字符串 时间O(n)空间O(1)

力扣1221:一次扫描解决分割平衡字符串 时间O(n)空间O(1)

题目重解给定一个仅包含'L'和'R'的字符串,要求将其分割成尽可能多的子串,且每个子串中'L'和'R'的数量相等。例如输入"R...

力扣933题:队列的妙用:如何高效统计最近请求

力扣933题:队列的妙用:如何高效统计最近请求

题目重解:我们需要设计一个能统计最近3000毫秒内请求次数的系统。每当新的请求到来时,它会带有时间戳t,我们需要返回过去3000毫秒内(包括当前)发生的请求总数。这就像是在时间轴上维护一个滑动窗口,只...

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

IOI 1994 洛谷1216:如何用动态规划高效解决数字三角形问题?附完整代码解析

题目重解给定一个由数字组成的三角形结构,从顶部出发,每次可以移动到下方相邻的数字,最终到达底部。我们的目标是找到一条路径,使得路径上经过的数字总和最大。这个问题在实际中有许多应用场景,如最优路径规划、...

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

一、题目解读洛谷B3617题要求将输入的八进制字符串转换为十六进制表示。题目需处理大数场景,且对输入合法性有明确限制(长度不超过1000,仅包含0-7字符)。由于八进制与十六进制无法直接转换,需借助十...

牛客14496题解:括号最大深度问题(栈思想与代码优化)

牛客14496题解:括号最大深度问题(栈思想与代码优化)

一、题目解读牛客14496题要求计算给定括号字符串中的最大深度。例如,对于字符串 "(()())",最大深度为2。题目考察对括号嵌套结构的理解,以及如何通过编程找到最深嵌套层次。二...

【洛谷1184题解析】用C++高效解决地点匹配问题(附代码与解题思路)

【洛谷1184题解析】用C++高效解决地点匹配问题(附代码与解题思路)

一、题目解读洛谷1184题要求处理一组地点列表与行程记录,统计其中匹配的天数。题目难点在于高效处理带有空格的字符串输入,以及快速判断每日行程是否在高手可去地点集合中。需要兼顾输入格式解析与算法效率。二...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。