思路简析
最初看到这道题的时候,进行了如下的思考
分别求出分子,分母 (我考虑用string来接受分数,再用substr来取分子分母,再分别对分子分母计算,部分代码如下
int N;
cin >> N;
vector<string> nums; //保存数字
vector<int> fenZi; //fenZi[i] 表示nums[i]的分子部分,包含负号
vector<int> fenMu; //fenMu[i] 表示nums[i]的分母部分,不包含负号
int fenZiResult, fenMuResult; //运算后的分子和分母
for (int i = 0; i < N; i++) {
string str;
cin >> str;
nums.push_back(str);
for (int j = 0; j < nums[i].size(); j++) {
if (nums[i][j] == '/') { //分别存储分子,分母
fenZi.push_back(stoi(nums[i].substr(0, j))); //stoi函数:将字符串转为int
fenMu.push_back(stoi(nums[i].substr(j + 1, nums[i].size() - 1)));
continue;
}
}
}
后来对比了其他的博客,发现解法可以更加优雅,要点如下
- 本题要输入分数,可以不定义为string,可以用 scanf(“%ld/%ld”, &a , &b); 来输入(说明中间以‘/’隔开)
- 没有必要将分子分母都存起来,直接每次遍历的时候进行运算后覆盖(以后构思问题的时候要注意这种思维)
- 运用到了gcd库函数求最大公约数,并利用最大公约数来化简分数
- 最后得到了一个无法再约分的分数,由于分子可能大于分母,还需进行判断再输出
思路来源:【PTA】 L1-009 N个数求和 (C++)-阿里云开发者社区
解法代码
#include <bits/stdc++.h>
using namespace std;
//用最大公约数将其变为最简式
void gys(long int &A , long int &B)
{
long int g = gcd(A , B); //gcd为库函数,求两数的大公约数
A /= g;
B /= g;
}
int main()
{
int n;
cin >> n;
long int a , b;
long int x , y;
scanf("%ld/%ld", &a , &b); //scanf的高级用法
for(int i = 1; i < n; i ++)
{
scanf("%ld/%ld", &x , &y);
a = a * y + b * x; //通分相加
b = b * y; //通分
gys(a,b);
}
if(a == 0) //分子为0,输出0
cout << "0" <<endl;
else if(a / b == 0) //a除b为0,说明a小于b,直接输出即可
cout << a << "/" << b << endl;
else if(a % b) //a大于b,分为整数和分数部分输出
cout << a / b << " " << a % b << "/" << b << endl;
else //a%b=0,即a能被b整除
cout << a / b << endl;
return 0;
}
相关知识
【C++】两个或多个数的最大公约数(gcd)、最小公倍数(lcm)算法 (手写)【C++】两个或多个数的最大公约数(gcd)、最小公倍数(lcm)算法_c++ gcd-CSDN博客
c++库函数gcd ,求最大公约数C++知识精讲8——gcd函数使用方法及实战讲解(例题为求最大公约数)_c++ gcd函数-CSDN博客