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. 连续运算的核心逻辑
你之前的问题大概率出在这里:
- 初始化
current_result为第一个分数; - 循环读取每个运算符和下一个分数,用
applyOperation更新current_result; - 所有运算完成后,输出最终结果。
这个逻辑就像手动计算连续运算一样:先算前两个数的结果,再用这个结果和下一个数运算,直到所有步骤完成。
测试示例
输入流程:
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
相关产品推荐
相关产品推荐

