力扣题目链接: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' 的数字,以及 '/', '+' 和 '-'。 ±分子/分母。如果输入的第一个分数或者输出的分数是正数,则 '+' 会被省略掉。用pair表示分数,然后不断模拟即可。
主要需要实现三个功能:
pii string2fraction(string s) {
pii ans;
// 判断分数的正负
if (s[0] == '-') {
ans.first = -1;
}
else {
ans.first = 1;
}
// 计算分子开始位置的下标
int l = 0;
if (s[0] == '-' || s[0] == '+') {
l++;
}
// 计算分子结束位置的下标
int r = l;
while (s[r] != '/')
r++;
// 计算分子分母
ans.first *= atoi(s.substr(l, r - l).c_str());
ans.second = atoi(s.substr(r + 1, s.size() - r -1).c_str());
return ans;
}
__gcd()函数调用时记得传入分子分母的绝对值,否则求得的最小公倍数可能会为负数。pii add(pii p1, pii p2) {
pii ans;
ans.second = p1.second * p2.second / __gcd(p1.second, p2.second);
ans.first = p1.first * (ans.second / p1.second) + p2.first * (ans.second / p2.second);
int gcd = __gcd(abs(ans.first), ans.second);
ans.first /= gcd, ans.second /= gcd;
return ans;
}
/即可。string fraction2string(pii f) {
return to_string(f.first) + "/" + to_string(f.second);
}
实现了上述三个功能,只需要在主函数中对原始字符串按加减号进行分割,并把每个分割出来的分数的值累加即可。
string fractionAddition(string expression) {
pii ans = {0, 1};
int last = 0; // 上一个处理到的字符的位置
for (int i = 1; i < expression.size(); i++) {
if (expression[i] == '+' || expression[i] == '-') { // 遇到加减号就开始分割
ans = add(ans, string2fraction(expression.substr(last, i - last)));
last = i;
}
}
ans = add(ans, string2fraction(expression.substr(last, expression.size() - last))); // 注意字符串末尾没有加减号,不要把最后一个分数遗漏了。
return fraction2string(ans);
}
拓展:
如果想要debug分数长啥样,可以直接重载运算符<<
ostream &operator << (ostream& out, pii& p) {
out << p.first << "/" << p.second;
return out;
}
这样,当想要debug时,就可以直接
pair<int, int> fraction = {1, 2};
cout << fraction << endl;
了。
typedef pair<int, int> pii;
ostream &operator << (ostream& out, pii& p) {
out << p.first << "/" << p.second;
return out;
}
class Solution {
private:
pii string2fraction(string s) {
pii ans;
if (s[0] == '-') {
ans.first = -1;
}
else {
ans.first = 1;
}
int l = 0;
if (s[0] == '-' || s[0] == '+') {
l++;
}
int r = l;
while (s[r] != '/')
r++;
ans.first *= atoi(s.substr(l, r - l).c_str());
ans.second = atoi(s.substr(r + 1, s.size() - r - 1).c_str());
// cout << s << " -> " << ans << endl;
return ans;
}
pii add(pii p1, pii p2) {
pii ans;
ans.second = p1.second * p2.second / __gcd(p1.second, p2.second);
ans.first = p1.first * (ans.second / p1.second) + p2.first * (ans.second / p2.second);
int gcd = __gcd(abs(ans.first), ans.second);
ans.first /= gcd, ans.second /= gcd;
return ans;
}
string fraction2string(pii f) {
return to_string(f.first) + "/" + to_string(f.second);
}
public:
string fractionAddition(string expression) {
pii ans = {0, 1};
int last = 0;
for (int i = 1; i < expression.size(); i++) {
if (expression[i] == '+' || expression[i] == '-') {
ans = add(ans, string2fraction(expression.substr(last, i - last)));
last = i;
}
}
ans = add(ans, string2fraction(expression.substr(last, expression.size() - last)));
return fraction2string(ans);
}
};
同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/126011320