算法训练 C++ CH08 01

问题描述
  已知一个有理数类Zrf_Ratio,实现如下的操作符重载形式:
  friend std::ostream& operator<<(std::ostream&, const zrf_Ratio&);//输出最简分数
  friend std::istream& operator>>(std::istream&, zrf_Ratio&);
  friend bool operator==(const zrf_Ratio&, const zrf_Ratio&);
  friend bool operator<(const zrf_Ratio&, const zrf_Ratio&);
测试
  测试时主程序会输入四个整数a, b, c, d,表示两个分数a/b和c/d。要求输出最简分数以及两个分数相等和大小的比较结果。
样例输入
1 7 26 25
样例输出
zrf is:1/7; ssh is:26/25
(zrf==ssh) is:0; (zrf<ssh) is:1

考验C++中类的相关知识,看了别的大佬的博客才知道,这题只需要提交下面的代码:

std::ostream& operator<<(std::ostream& out, const zrf_Ratio& t)
{
    out << t.num << "/" << t.den;
    return out;
}

std::istream& operator>>(std::istream& in, zrf_Ratio& t)
{
    in >> t.num >> t.den;
    return in;
}

bool operator==(const zrf_Ratio& t1, const zrf_Ratio& t2)
{
    return (t1.num == t2.num)&&(t1.den == t2.den);
}

bool operator<(const zrf_Ratio& t1, const zrf_Ratio& t2)
{
    if (t1.num != 0 && t2.num != 0)
    {   //根据t.num的正负来判断t的正负 
        if ((t1.num > 0 && t2.num > 0) || (t1.num < 0  && t2.num < 0))
        {
            return (t1.num * t2.den) < (t1.den * t2.num);
        }
        else if (t1.num < 0 && t2.num > 0)
        {
            return 1;
        }
        else return 0;
    }
    else if(t1.num == 0 && t2.num != 0)
    {
        if (t2.num > 0)         return 1;
        else            return 0;
    }
    else if(t1.num != 0 && t2.num == 0)
    {
        if (t1 < 0)         return 1;
        else            return 0;
    }
    else
    {
        return 0;
    }
}

完整的:

#include <iostream>
#include <cassert>
using namespace std;
class zrf_Ratio
{
     friend std::ostream& operator<<(std::ostream&, const zrf_Ratio&);
     friend std::istream& operator>>(std::istream&, zrf_Ratio&);
     friend bool operator==(const zrf_Ratio&, const zrf_Ratio&);
     friend bool operator<(const zrf_Ratio&, const zrf_Ratio&);
public:
     zrf_Ratio(int=0,int=1);
     zrf_Ratio(const zrf_Ratio&);

private:
     int num;
     int den;
     void reduce();//化为最简分数
};

//补充完整构造函数
std::ostream& operator<<(std::ostream& out, const zrf_Ratio& t)
{
    out << t.num << "/" << t.den;
    return out;
}

std::istream& operator>>(std::istream& in, zrf_Ratio& t)
{
    in >> t.num >> t.den;
    return in;
}

bool operator==(const zrf_Ratio& t1, const zrf_Ratio& t2)
{
    return (t1.num == t2.num)&&(t1.den == t2.den);
}

bool operator<(const zrf_Ratio& t1, const zrf_Ratio& t2)
{
    if (t1.num != 0 && t2.num != 0)
    {   //根据t.num的正负来判断t的正负 
        if ((t1.num > 0 && t2.num > 0) || (t1.num < 0  && t2.num < 0))
        {
            return (t1.num * t2.den) < (t1.den * t2.num);
        }
        else if (t1.num < 0 && t2.num > 0)
        {
            return 1;
        }
        else return 0;
    }
    else if(t1.num == 0 && t2.num != 0)
    {
        if (t2.num > 0)         return 1;
        else            return 0;
    }
    else if(t1.num != 0 && t2.num == 0)
    {
        if (t1 < 0)         return 1;
        else            return 0;
    }
    else
    {
        return 0;
    }
}

//公有成员函数:
zrf_Ratio::zrf_Ratio(int num, int den) : num(num), den(den)
{
     reduce();
}

zrf_Ratio::zrf_Ratio(const zrf_Ratio& r) : num(r.num), den(r.den)
{

}

//私有成员函数:
void swap(int &m, int &n)
{
     int t;
     t=m;
     m=n;
     n=t;
}

int zrf_Gcd(int m, int n)
{
     if (m<n)
         swap(m,n);
     assert(n>=0);
     while (n>0)
     {
         int r=m%n;
         m = n;
         n = r;
     }
     return m;
}

void zrf_Ratio::reduce()
{
     if (num == 0 || den == 0)
     {
         num = 0;
         den = 1;
         return;
     }
     if (den < 0)
     {
         den *= -1;
         num *= -1;
     }
     if (num == 1)
         return;
     int sgn = (num<0?-1:1);
     int g = zrf_Gcd(sgn*num,den);
     num /= g;
     den /= g;
}

int main()
{
     int a = 0, b = 0, c = 0, d = 0;
     cin >> a >> b >> c >> d;
     zrf_Ratio zrf(a, b),ssh(c, d);
     std::cout<<"zrf is:"<<zrf<<"; ssh is:"<<ssh<<'\n';
     std::cout<<"(zrf==ssh) is:"<<(zrf==ssh)<<"; (zrf<ssh) is:"<<(zrf<ssh) <<endl;
     return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值