一.题目描述
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;
}