What sort of rational realization is elegant?
In my opinion, it should meet the following characteristics
1. Conform to the object-oriented encapsulation feature, data hiding (because there is only one class, no encapsulation and polymorphism is considered).
2. The Declaration and implementation are separated, the interface is clear and natural, there are enough basic functions and not redundant.
3. Simple and Clear Code
4. It is best to read without comment, variable name, method name can be seen in the name of the known meaning
5.do not repeat yourself, do not repeat the work
6. Throw an exception in case of error, abort the program, rather than hide the error in the internal implementation, bury the hidden trouble.
The rational implementation of the following I think is more elegant, it conforms to the above 5 characteristics
1.public, private display of its data hiding features, numerator, denominator class users are inaccessible
2. Provides a basic operation subtraction the inverse of the reciprocal number, and overloads the +,-,*,/operator, which can be used more clearly and naturally
3. The implementation of each method is not complex in itself, the implementation of the GCD function is very concise
4. The method name, the numerator denominator basically can see the name to understand the meaning
5. Subtraction is achieved by adding the opposite number, and division is achieved by multiplying by the reciprocal, which can reflect this
6. When the denominator is zero, the numerator is null to throw an exception when the inverse is obtained
Rational.h
#ifndef rational_#define rational_#include "MyException.h" #include <iostream>using namespace Std;class Rational {public: Rational (int x, int y);//passing in numerator denominator construct fraction rational (string s);//construct fractions from string rational nega ();//Inverse number rational reci () ;//Countdown bool IsEqual (Rational that); Rational add (rational that);//Add Rational sub (rational that);//Subtract rational mul (rational that);//Multiplication Rational Div (rational);//Division void Output (ostream &out) const;//output Method int Getnumer () {return numer;} int Getdenom () {return denom;} Private: int numer;//numerator int denom;//denominator int gcd (int a, int b) const {return (b==0)? A:GCD (b, a% b);} Greatest common divisor}; #endif//Rational_define
Rational.cpp
#include "rational.h" #include "myException.h" #include <cstdlib>using namespace std; rational::rational (int x, int y) {//pass in numerator denominator construct fraction if (y==0) throw new Illegaldenominatorvalue (); Numer = x; Denom = y;} Constructs a fraction from a string rational::rational (string s) {int pos = S.find ('/', 0); if (pos <= 0 | | pos >= s.length ()-1) throw new Illegalinputexpression (); Numer = Atoi (S.substr (0,pos). C_STR ()); Denom = Atoi (S.substr (Pos+1,s.length ()-pos-1). C_STR ()); if (Denom = = 0) throw new Illegaldenominatorvalue ();} The inverse number rational rational::nega () {return rational (-numer, denom);} Inverse Rational Rational::reci () {if (Numer = = 0) throw new noreciprocal (); Return Rational (Denom,numer);} equal bool Rational::isequal (Rational that) {return Numer * that.denom = = Denom * That.numer;} Addition Rational rational::add (rational that) {return rational (Numer * that.denom + denom * that.numer,denom * that.denom); }//subtraction Rational rational::sub (rational that) {return Add (That.nega ());} Multiplication rationalRational::mul (rational that) {return rational (Numer * that.numer, Denom * that.denom);} Division Rational Rational::d IV (Rational that) {return Mul (That.reci ());} Output void Rational::output (ostream &out) const{int c = gcd (numer,denom); int c = 1; out<<numer/c<< "/" <<denom/c; }//Output operator overload ostream& operator<< (ostream& out, const rational& r) {r.output (out); return out;} operator overload rational operator + (rational A, rational b) {return a.add (b);} Rational operator-(rational A, rational b) {return a.sub (b);} Rational operator * (Rational A, rational b) {return A.mul (b);} Rational operator/(rational A, rational b) {return a.div (b);}
MyException.h
Exception classes for various error types#ifndef Myexceptions_#define myexceptions_#include <string> #include <iostream>using namespace std;//illegal denominator valueclass illegaldenominatorvalue{public:illegaldenom Inatorvalue (String themessage = "Denominator must be nonezero!") {message = Themessage; } void Outputmessage () {cout << message << Endl;} Private:string message;};/ /illegal input Expressionclass illegalinputexpression{public:illegalinputexpression (String themessage = "illegal Input Expression ") {message = Themessage; } void Outputmessage () {cout << message << Endl;} Private:string message;};/ /Countdown Class noreciprocal{public:noreciprocal (String themessage = "No reciprocal with numerator=0") {message = Themessage; } void Outputmessage () {cout << message << Endl;} Private:string message;}; #endif
Test.cpp
#include "rational.h" #include "Rational.cpp" using namespace Std;int Main () { rational A; Rational B ("quarter"); Rational C ("1/0"); Rational C ("1/"); cout<< "a = \ t" << a <<endl; cout<< "b = \ t" << b <<endl; cout<< "-a = \ T" << A.nega () <<endl; cout<< "1/b =\t" << b.reci () <<endl; cout<< "A.add (b) =\t" << a.add (b) <<endl; cout<< "A.sub (b) =\t" << a.sub (b) <<endl; cout<< "A.mul (b) =\t" << A.mul (b) <<endl; cout<< "A.div (b) =\t" << a.div (b) <<endl; cout<< "A+b =\t" << a+b<<endl; cout<< "A-=\t" << a-b<<endl; cout<< "A*b =\t" << a*b<<endl; cout<< "A/C =\t" << a/b<<endl; return 0;}
As an example, let's look at how to use this class to solve the problem of "solving a one-dimensional fractional equation such as a/b x+ C/D =/F"
#include "rational.h" #include "Rational.cpp" using namespace Std;int main () {while (1) {cout << "input equation: shaped like A/b x + d/c = f/e "<<endl; Char arr[50]; Cin.getline (ARR, 50); String equation (ARR); cout << equation <<endl;//A/b x + d/c = f/e int pos_x = equation.find (' x ', 0); int pos_p = equation.find (' + ', 0); int pos_e = equation.find (' = ', 0); Rational Coe (equation.substr (0,pos_x))//A/b Rational B (Equation.substr (pos_p+1,pos_e-pos_p));//d/c Rational C (Equation.substr (Pos_e+1,equation.length ()-pos_e));//f/e//cout<< "Coe =" <<coe<<endl; cout<< "b =" <<b<<endl; cout<< "C =" <<c<<endl; if (coe.getnumer () = = 0 && b.isequal (c)) cout<< "X∈q" <<endl; else if (coe.getnumer () = = 0 &&!b.isequal (c)) cout<< "No Solution" <<endl; else cout<< "solution x =" << (c-b)/coe<<endl<<endl; System ("pause"); System ("CLS");}}
The code is as follows
Main.cpp
#include "rational.h" #include "Rational.cpp" using namespace Std;int main () {while (1) {cout << "input equation: shaped like A/b x + d/c = f/e "<<endl; Char arr[50]; Cin.getline (ARR, 50); String equation (ARR); cout << equation <<endl;//A/b x + d/c = f/e int pos_x = equation.find (' x ', 0); int pos_p = equation.find (' + ', 0); int pos_e = equation.find (' = ', 0); Rational Coe (equation.substr (0,pos_x))//A/b Rational B (Equation.substr (pos_p+1,pos_e-pos_p));//d/c Rational C (Equation.substr (Pos_e+1,equation.length ()-pos_e));//f/e//cout<< "Coe =" <<coe<<endl; cout<< "b =" <<b<<endl; cout<< "C =" <<c<<endl; if (coe.getnumer () = = 0 && b.isequal (c)) cout<< "X∈q" <<endl; else if (coe.getnumer () = = 0 &&!b.isequal (c)) cout<< "No Solution" <<endl; else cout<< "solution x =" << (c-b)/coe<<endl<<endl; System ("pause"); System ("CLS");}}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
How to gracefully implement a C + + fractional class (Rational)?