西北农林科技大学2024学年C++面向对象程序设计OJ——T12 有理数类的设计与实现

一.题目描述

Description

定义有理数类(分母不为0的分数,分子分母均为整数)CRational,实现相应运算符的重载。

(1)定义私有数据成员:分子int iUp;分母int iDown。

(2)定义私有成员函数:void Reduce()和int Gcd(int l, int r),分别用于有理数的约简和求两个整数的最大公约数。其中,在约简时需要求取分子与分母的最大公约数。

(3)定义构造函数,在构造函数体内可调用Reduce对有理数进行约简。

(4)将非运算符!重载为公有成员函数用于判断分母是否为0。

(5)将负号-重载为公有成员函数用于求有理数的负数。

(6)将前置++、前置--、后置++、后置--重载为公有成员函数,实现有理数自增1或自减1。

(7)将+、-、*、/重载为友员函数,实现有理数的加减乘除。

(8)将<、>重载为友员函数,实现有理数的大小关系比较。

(9)重载输入流运算符<<和输出流运算符>>,分别用于有理数的输出和输入。其中,输入输出格式均为“分子/分母”,若输出为整数,则直接输出整数。

在main函数中,根据输入的分子和分母定义两个有理数对象a和b。再定义几个有理数对象分别用于表示a和b的加、减、乘、除、前置自增a、前置自减a、后置自增a、后置自减a,并依次各个对象的结果。最后依次用<、<=、>、>=比较a和b的大小关系,并依次输出比较结果(true或false)。若遇到分母为零则输出“The denominator cannot be zero!”。

int main()
{
    Rational a;
    Rational b;

    cout << "Input rational a: " << endl;
    cin >> a;
    cout << "Input rational b: " << endl;
    cin >> b;

    if (!a && !b)
    {
        cout << "a+b: " << (a+b) << endl;
        cout << "a-b: " << (a-b) << endl;
        cout << "a*b: " << (a*b) << endl;
        cout << "a/b: " << (a/b) << endl;
        cout << "-a: " << (-a) << endl;
        cout << "++a: " << (++a) << endl;
        cout << "--a: " << (--a) << endl;
        cout << "a++: " << (a++) << endl;
        cout << "a--: " << (a--) << endl;
        cout << "a>b: " << ((a>b)?"true" : "false") << endl;
        cout << "a<b: " << ((a<b)?"true" : "false") << endl;
    }

    return 0;
}

二.输入与输出

Input

两个有理数a和b

Output

有理数a和b的加、减、乘、除以及前置自增a、前置自减a、后置自增a、后置自减a、有理数a和b比较大小的结果

Sample Input 1 

1/3
2/0

Sample Output 1

Input rational a: 
Input rational b: 
The denominator cannot be zero!

Sample Input 2 

4/3
3/2

Sample Output 2

Input rational a: 
Input rational b: 
a+b: 17/6
a-b: -1/6
a*b: 2
a/b: 8/9
-a: -4/3
++a: 7/3
--a: 4/3
a++: 4/3
a--: 7/3
a>b: false
a<b: true

Sample Input 3 

5/8
0/1

Sample Output 3

Input rational a: 
Input rational b: 
a+b: 5/8
a-b: 5/8
a*b: 0/8
a/b: The denominator cannot be zero!
5/0
-a: -5/8
++a: 13/8
--a: 5/8
a++: 5/8
a--: 13/8
a>b: true
a<b: false

Sample Input 4 

-3/4
-8/3

Sample Output 4

Input rational a: 
Input rational b: 
a+b: -41/12
a-b: 23/12
a*b: 2
a/b: 9/32
-a: 3/4
++a: 1/4
--a: -3/4
a++: -3/4
a--: 1/4
a>b: true
a<b: false

Sample Input 5 

16/24
32/496

Sample Output 5

Input rational a: 
Input rational b: 
a+b: 68/93
a-b: 56/93
a*b: 4/93
a/b: 31/3
-a: -2/3
++a: 5/3
--a: 2/3
a++: 2/3
a--: 5/3
a>b: true
a<b: false

三.代码

//有理数
#include<iostream>
#include<string>
#include<algorithm>
#include<sstream>
using namespace std;
class CRational {
    int iup;
    int idown;
    void Reduce() {
        int t = abs(Gcd(iup, idown));
        iup = iup / t;
        idown = idown / t;//
        if (idown < 0) {
            idown = -idown;
            iup = -iup;
        }
    }
    int Gcd(int l, int r) {
        if (l == 0) return r;
        else return Gcd(r%l, l);
    }
public:
    CRational() {
        iup = idown = 1;
    }
    CRational(int _i,int _j):iup(_i),idown(_j){
        Reduce();
    }
    bool operator!() {
        if (idown == 0) {
            cout << "The denominator cannot be zero!" << endl;
            return false;
        }
        else return true;
    }
 
 
    CRational operator-() {
        CRational t;
        t.iup = -iup;
        t.idown = idown;
        t.Reduce();
        return t;
    }
 
    CRational operator++() {
        iup = iup + idown;
        this->Reduce();
        return *this;
    }
 
    CRational operator--() {
        iup = iup - idown;
        this->Reduce();
        return *this;
    }
    CRational operator++(int x){
        CRational r = *this;
        iup = iup + idown;
        r.Reduce();
        return r;
    }
    CRational operator--(int x) {
        CRational r = *this;
        iup = iup - idown;
        r.Reduce();
        return r;
    }
 
    friend CRational operator+(CRational& a, CRational& b) {
        CRational c;
        c.iup = a.iup * b.idown + a.idown * b.iup;
        c.idown = a.idown * b.idown;
        c.Reduce();
        return c;
    }
    friend CRational operator-(CRational& a, CRational& b) {
        CRational c;
        c.iup = a.iup * b.idown - a.idown * b.iup;
        c.idown = a.idown * b.idown;
        c.Reduce();
        return c;
    }
    friend CRational operator*(CRational& a, CRational& b) {
        CRational c;
        c.iup = a.iup * b.iup;
        c.idown = a.idown * b.idown;
        c.Reduce();
        return c;
    }
 
    friend CRational operator/(CRational& a, CRational& b) {
        CRational c;
        c.iup = a.iup * b.idown;
        c.idown = a.idown * b.iup;
        if (a.iup != 0 && b.iup != 0) {
            c.Reduce();
        }
        return c;
    }
 
    friend bool operator>(const CRational & a,const CRational & b) {
        return(a.iup / (double)a.idown > b.iup / (double)b.idown);
    }
 
    friend bool operator<(CRational& a, CRational& b) {
        return(a.iup / (double)a.idown < b.iup / (double)b.idown);
    }
 
    friend ostream &operator<<(ostream &output,const CRational &r) {
        if (r.idown == 0) output << "The denominator cannot be zero!" << endl<<r.iup<<"/0";
        else if (r.idown == 1) output << r.iup ;
        else output << r.iup << "/" << r.idown ;
        return output;
    }
 
    friend istream& operator>>(istream& in, CRational& a)
    {
        
        int x, y;
        string s;
        cin >> s;
        for (int i = 0; i < s.size(); i++) {
            if (s[i] == '/') s[i] = ' ';
        }
        istringstream iss(s);
        iss >> x >> y;
        a.iup = x;
        a.idown = y;
        return in;
        
        
    }
};
 
 
int main()
 
{
    CRational a;
 
    CRational b;
 
    cout << "Input rational a: " << endl;
 
    cin >> a;
 
    cout << "Input rational b: " << endl;
 
    cin >> b;
 
    if (!a && !b)
 
    {
 
        cout << "a+b: " << (a + b) << endl;
 
        cout << "a-b: " << (a - b) << endl;
 
        cout << "a*b: " << (a * b) << endl;
 
        cout << "a/b: " << (a / b) << endl;
 
        cout << "-a: " << (-a) << endl;
 
        cout << "++a: " << (++a) << endl;
 
        cout << "--a: " << (--a) << endl;
 
        cout << "a++: " << (a++) << endl;
 
        cout << "a--: " << (a++) << endl;
 
        cout << "a>b: " << ((a > b) ? "true" : "false") << endl;
 
        cout << "a<b: " << ((a < b) ? "true" : "false") << endl;
 
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自由永远自由

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值