题目
计算机设计与算法分析课程,第一次作业D题
最先联想到的就是最大公约数和最小公倍数,直接框框写代码
按照的思路完全是:分数加法时的简单过程,
- 找到两个分母的最小公倍数,然后分母都乘到此数;分子也对应乘
- 两个分数相加
- 找到分子分母的最大公约数,然后约分,得到结果
- 如果分母是1,则直接输出分子;否则输出分子分母
#include <iostream>
#include <string>
using namespace std;
int getmaxgys(int m, int n){ //最大公约数
if(m < n){
int tmp = n;
n = m;
m = tmp;
}
while(m % n){
int tmp = m % n;
m = n;
n = tmp;
}
return n;
}
int getmingbs(int m, int n){ //最小公倍数
int a = m, b = n;
if(m < n){
int tmp = n;
n = m;
m = tmp;
}
while(m % n){
int tmp = m % n;
m = n;
n = tmp;
}
return a * b * n;
}
int main() {
int n;
cin >> n;
string s;
int a1 = 0, a2 = 1, b1, b2;
for(int i = 0; i < n;i++){
cin >> s;
int ind = s.find('/');
b1 = atoi(s.substr(0,ind).c_str());
b2 = atoi(s.substr(ind+1).c_str());
int mmin = getmingbs(a2, b2);
a1 *= mmin / a2;
b1 *= mmin / b2;
a1 += b1;
a2 = mmin;
// 约分
int mmax = getmaxgys(a1, a2);
a1 /= mmax;
a2 /= mmax;
}
if(a2 != 1)cout << a1 << '/' << a2;
else cout << a1;
cout<< endl;
return 0;
}
写完之后,AC了,但是就感觉很蠢。特别是最大公约数和最小公倍数的函数还是分开写的。没想到什么好办法。。毕竟返回值就一个,而且在一次分数相加过程中处理的对象还不一样。
然后再审题就发现原题数字给的都很小,完全没必要两个分母必须要乘到最小公倍数才行,分母直接乘到俩分母的乘积分子直接对角相乘就行了。
约分也没有采取没加完一个分数就约分一次(也许我这个虽然麻烦,但是数如果给的大了就算是最佳方案了吧哈哈)
下边附上别人简略版的代码
#include<iostream>
using namespace std;
int main()
{
int n, top = 0, bottom = 1;
char trash;
cin >> n;
for (int i = 0; i < n; i++)
{
int newtop, newbottom;
cin >> newtop >> trash >> newbottom;
top = top * newbottom + newtop * bottom;
bottom = bottom * newbottom;
}
int GCD(int a, int b);
int c = GCD(top, bottom);
top /= c;
bottom /= c;
if (bottom == 1)cout << top;
else cout << top << "/" << bottom;
}
int GCD(int a, int b)//辗转相除法
{
if(b==0)return a;
else return GCD(b,a%b);
}
除了上边说的内容,主要值得学习的有两个部分:
- 读入的时候,采用(数字、字符、数字)的方式读入,方便快捷。(感觉我有点太依赖string这个库了)
- 最大公约数的求法,这样写法简便,值得记住。(要是求最小公倍数就直接再乘原来的a和b)
参考链接:
https://blog.csdn.net/weixin_44351043/article/details/101712357