1.分数相加,两个分数分别是1/5和7/20,它们相加后得11/20。方法是先求出两个分数分母的最小公倍数,通分后,再求两个分子的和,最后约简结果分数的分子和分母(如果两个分数相加的结果是4/8,则必须将其约简成最简分数的形式1/2),即用分子分母的最大公约数分别除分子和分母。求m、 n最大公约数的一种方法为:将m、 n较小的一个数赋给变量k,然后分别用{k,k-1,k-2,…,1}中的数(递减)去除m和n,第一个能把m和n同时除尽的数就是m和n 的最大公约数。假定m、 n的最大公约数是v,则它们的最小公倍数就是m*n/v。试建立一个分数类Fract,完成两个分数相加的功能。
具体要求如下:
- 私有数据成员
- int num,den;num为分子,den为分母。
- 公有成员函数
- Fract(int a=0,int b=1):构造函数,用a 和 b 分别初始化分子 num、分母 den。
- int ged(int m, int n):求 m、 n 的最大公约数。此函数供成员 add()函数调用。
- Fract add(Fract f):将参数分数 f 与对象自身相加,返回约简后的分数对象。
- void show():按照 num/den 的形式在屏幕上显示分数。
- 在主程序中定义两个分数对象 f1 和 f2,其初值分别是 1/5 和 7/20,通过 f1 调用成员函数 add 完成 f1 和 f2 的相加,将得到的分数赋给对象 f3,显示分数对象 f3。
#include<iostream>
using namespace std;
class Fract{
int num,den;
public:
Fract(int a=0,int b=1):num(a),den(b){}
//欧几里得算法又称辗转相除法 求约数
int ged(int m,int n){
if(n>m){
int t=n;
n=m;
m=t;
}
int k=m%n;
while(k!=0){
m=n;
n=k;
k=m%n;
}
return n;
}
/*
int ged(int m,int n){
int k;
if(n<m)k=n;
else k=m;
for(int i=k;i>=1;i--){
if(m%k==0&&n%k==0){
return k;
}
}
return 1;//非常重要,别漏了!
}
*/
//直接通分
Fract add(Fract f){
Fract t(num*f.den+f.num*den,f.den*den);
t.den/=ged(t.den,t.num);
t.num/=ged(t.den,t.num);
return t;
}
/*
Fract add(Fract f){
int a1=num,a2=f.num;//分子
int b1=den,b2=f.den;//分母
int b3 = b1*b2/ged(b1,b2);//通分后的分母
int a3=b3/b1*a1+b3/b2*a2;//通分后,两分子之和
int v= ged(a3,b3);
a3/=v;
b3/=v;
return Fract(a3,b3);
}
*/
void show(){
cout<<num<<"/"<<den<<endl;
}
};
int main(){
Fract f1(1,5),f2(7,20),f3=f1.add(f2);
f1.show();
f2.show();
f3.show();
return 0;
}