来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/fraction-addition-and-subtraction
题目描述
给定一个表示分数加减运算的字符串 expression ,你需要返回一个字符串形式的计算结果。
这个结果应该是不可约分的分数,即最简分数。 如果最终结果是一个整数,例如 2,你需要将它转换成分数形式,其分母为 1。所以在上述例子中, 2 应该被转换为 2/1。
示例 1:
输入: expression = "-1/2+1/2"
输出: "0/1"
示例 2:
输入: expression = "-1/2+1/2+1/3"
输出: "1/3"
示例 3:
输入: expression = "1/3-1/2"
输出: "-1/6"
提示:
输入和输出字符串只包含 '0' 到 '9' 的数字,以及 '/', '+' 和 '-'。
输入和输出分数格式均为 ±分子/分母。如果输入的第一个分数或者输出的分数是正数,则 '+' 会被省略掉。
输入只包含合法的最简分数,每个分数的分子与分母的范围是 [1,10]。 如果分母是1,意味着这个分数实际上是一个整数。
输入的分数个数范围是 [1,10]。
最终结果的分子与分母保证是 32 位整数范围内的有效整数。
解题思路
这道题的限制条件比较多,可以采用一定的取巧办法。
首先是解析字符串,这个就不多加阐述了,将字符串解析为符号组,分子组和分母组。
由于分母的取值范围是1-10,所以可以将所有分数通分到分母为2520(1-10的最小公倍数)的形态。
然后将分子相加取得一个sum,然后将这个sum和2520约分就可以了。
由于分母的取值范围是1-10,所以约分也可以取巧,直接从遍历从10到1,如果分子分母可以同时整除则分子分母同时除这个数。
代码展示
class Solution { public: /*1- 10 的最小公倍数为2520 所以可以通分到分母为2520计算*/ int iMax = 2520; string fractionAddition(string expression) { string strRet,strNumber; vector<int> viNumerators, viDenominators, viSign; int iSum = 0; if (expression.size() == 0) return strRet; if (expression.at(0) != '-') expression = "+" + expression; for (auto c : expression) { switch (c) { case '+': if (!strNumber.empty()) viDenominators.push_back(atoi(strNumber.c_str())); strNumber.clear(); viSign.push_back(0); break; case '-': if (!strNumber.empty()) viDenominators.push_back(atoi(strNumber.c_str())); strNumber.clear(); viSign.push_back(1); break; case '/': if (!strNumber.empty()) viNumerators.push_back(atoi(strNumber.c_str())); strNumber.clear(); break; default: strNumber.push_back(c); } } if (!strNumber.empty()) viDenominators.push_back(atoi(strNumber.c_str())); if (viSign.size() != viNumerators.size() || viSign.size() != viDenominators.size()) return strRet; for (int i = 0; i < viSign.size(); i++) { viNumerators[i] = viNumerators[i] * (iMax / viDenominators[i]); } for (int i = 0; i < viSign.size(); i++) { iSum += viSign[i] ? -1 * viNumerators[i] : viNumerators[i]; } for (int i = 10; i > 0; i--) { if (iSum % i == 0 && iMax % i == 0) { iSum = iSum / i; iMax = iMax / i; } } strRet = to_string(iSum) + "/" + to_string(iMax); return strRet; } };
运行结果