You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++有理数运算实现问题:多分数连续运算及存储求解

解决C++连续分数运算问题:Rational类+连续运算实现

我来帮你搞定这个连续分数运算的问题!你之前卡壳在连续运算的串联逻辑上,其实核心就是维护一个当前结果变量,依次用每个运算符和下一个分数更新它就行。下面是完整的可运行代码,附带详细解释。

完整实现代码

#include <iostream>
#include <vector>
#include <stdexcept>
#include <cstdlib>

// 自定义最大公约数计算,兼容C++17之前的标准
int gcd(int a, int b) {
    a = std::abs(a);
    b = std::abs(b);
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

class Rational {
private:
    int numerator;   // 分子
    int denominator; // 分母

    // 约分函数:确保分数最简,且分母为正
    void reduce() {
        if (denominator == 0) {
            throw std::invalid_argument("Denominator cannot be zero!");
        }
        int common_divisor = gcd(numerator, denominator);
        numerator /= common_divisor;
        denominator /= common_divisor;

        // 把符号统一放到分子上,分母始终为正
        if (denominator < 0) {
            numerator *= -1;
            denominator *= -1;
        }
    }

public:
    // 构造函数:默认值为0/1
    Rational(int num = 0, int den = 1) : numerator(num), denominator(den) {
        reduce();
    }

    // 重载加法运算符
    Rational operator+(const Rational& other) const {
        int new_num = numerator * other.denominator + other.numerator * denominator;
        int new_den = denominator * other.denominator;
        return Rational(new_num, new_den);
    }

    // 重载减法运算符
    Rational operator-(const Rational& other) const {
        int new_num = numerator * other.denominator - other.numerator * denominator;
        int new_den = denominator * other.denominator;
        return Rational(new_num, new_den);
    }

    // 重载乘法运算符
    Rational operator*(const Rational& other) const {
        int new_num = numerator * other.numerator;
        int new_den = denominator * other.denominator;
        return Rational(new_num, new_den);
    }

    // 重载除法运算符
    Rational operator/(const Rational& other) const {
        if (other.numerator == 0) {
            throw std::invalid_argument("Cannot divide by zero!");
        }
        int new_num = numerator * other.denominator;
        int new_den = denominator * other.numerator;
        return Rational(new_num, new_den);
    }

    // 重载输出运算符:自动处理整数形式(分母为1时)
    friend std::ostream& operator<<(std::ostream& os, const Rational& r) {
        if (r.denominator == 1) {
            os << r.numerator;
        } else {
            os << r.numerator << "/" << r.denominator;
        }
        return os;
    }

    // 工具函数:根据运算符字符执行对应运算
    static Rational applyOperation(const Rational& current, char op, const Rational& next) {
        switch(op) {
            case '+': return current + next;
            case '-': return current - next;
            case '*': return current * next;
            case '/': return current / next;
            default: throw std::invalid_argument("Invalid operator: " + std::string(1, op));
        }
    }
};

int main() {
    try {
        int n;
        std::cout << "Enter the number of operations: ";
        std::cin >> n;

        if (n <= 0) {
            throw std::invalid_argument("n must be a positive integer!");
        }

        // 读取第一个分数(连续运算的初始值)
        int num, den;
        std::cout << "Enter the first fraction (numerator denominator): ";
        std::cin >> num >> den;
        Rational current_result(num, den);

        // 读取n组「运算符 分子 分母」
        std::cout << "Enter " << n << " lines of 'operator numerator denominator':\n";
        for (int i = 0; i < n; ++i) {
            char op;
            int next_num, next_den;
            std::cin >> op >> next_num >> next_den;
            Rational next_frac(next_num, next_den);
            // 更新当前结果
            current_result = Rational::applyOperation(current_result, op, next_frac);
        }

        // 读取结束符'.'并输出结果
        char end_char;
        std::cout << "Enter '.' to get the final result: ";
        std::cin >> end_char;
        if (end_char != '.') {
            throw std::invalid_argument("Expected '.' to execute calculation!");
        }

        std::cout << "Final simplified result: " << current_result << std::endl;

    } catch (const std::exception& e) {
        std::cerr << "Error: " << e.what() << std::endl;
        return 1;
    }
    return 0;
}

关键部分解释

1. Rational类核心设计

  • 自动约分:构造函数和所有运算后都会调用reduce(),确保分数始终是最简形式,且分母为正(符号统一在分子上)。
  • 运算符重载:重载了+、-、*、/,返回新的Rational对象,避免修改原对象。
  • 工具函数applyOperation:把字符运算符映射到对应的运算,方便循环中调用,不用写一堆if-else。

2. 连续运算的核心逻辑

你之前的问题大概率出在这里:

  1. 初始化current_result为第一个分数;
  2. 循环读取每个运算符和下一个分数,用applyOperation更新current_result;
  3. 所有运算完成后,输出最终结果。

这个逻辑就像手动计算连续运算一样:先算前两个数的结果,再用这个结果和下一个数运算,直到所有步骤完成。

测试示例

输入流程:

Enter the number of operations: 2
Enter the first fraction (numerator denominator): 1 2
Enter 2 lines of 'operator numerator denominator':
+ 3 4
* 5 6
Enter '.' to get the final result: .

输出结果:

Final simplified result: 25/24

计算过程:(1/2 + 3/4) = 5/4,然后5/4 * 5/6 = 25/24,自动约分后输出。

你之前可能踩的坑

  • 没有维护当前结果变量,而是试图一次性处理所有分数和运算符;
  • 运算符重载没有返回新对象,而是修改原对象,导致中间结果混乱;
  • 没有自动约分,导致数值过大或者结果不是最简形式;
  • 输入处理逻辑混乱,没有区分初始分数和后续的运算步骤。

内容的提问来源于stack exchange,提问作者Erick.1993

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:41:18