MyTetra Share
Делитесь знаниями!
Калькулятор дробей
Время создания: 16.08.2017 16:32
Раздел: Computer - Programming - C++ - Coursera White_Belt

Итак, теперь у нас с вами есть полноценный тип для представления обыкновенных дробей: класс Rational интегрирован в язык с помощью перегрузки операторов и не позволяет выполнять некорректные операции за счёт выбрасывания исключений. Давайте на основе класса Rational создадим простой калькулятор для обыкновенных дробей.

Вам надо написать программу, которая считывает из стандартного ввода одну строку в формате ДРОБЬ_1 операция ДРОБЬ_2ДРОБЬ_1 и ДРОБЬ_2 имеют формат X/Y, где X — целое, а Y — целое неотрицательное число. операция — это один из символов '+', '-', '*', '/'.

Если ДРОБЬ_1 или ДРОБЬ_2 является некорректной обыкновенной дробью, ваша программа должна вывести в стандартный вывод сообщение "Invalid argument". Если считанная операция — это деление на ноль, выведите в стандартный вывод сообщение "Division by zero". В противном случае выведите результат операции.

Пример

stdin

stdout

1/2 + 1/3

5/6

1/2 + 5/0

Invalid argument

4/5 / 0/8

Division by zero



#include <iostream>

#include <sstream>

#include <vector>

// #include <set>

// #include <map>

#include <exception>


using namespace std;


int Divider(const int& n, const int& d) {

if(n == d)

{

return n;

}

else if(n == 0)

{

return n;

}

else

{

int dividend_t = 0;

int divider_t = 0;

int reminder = 0;


if(n > d)

{

dividend_t = n;

divider_t = d;

}

else

{

dividend_t = d;

divider_t = n;

}


reminder = dividend_t % divider_t;

while(reminder != 0)

{

dividend_t = divider_t;

divider_t = reminder;

reminder = dividend_t % divider_t;

}

if(divider_t < 0)

return -divider_t;

else return divider_t;

}


}


class Rational {

public:

Rational() {

p = 0;

q = 1;

}


Rational(int numerator, int denominator) {

Initialize(numerator, denominator);

}


void Initialize(const int& numer, const int& denom)

{

if(denom == 0)

{

throw invalid_argument("Invalid argument");

}

else if(numer == 0)

{

p = 0;

q = 1;

}

else

{

if(denom < 0)

{

p = -numer;

q = -denom;

}

else

{

p = numer;

q = denom;

}

int divider = Divider(p, q);

p /= divider;

q /= divider;

}

}


int Numerator() const {

return p;

}


int Denominator() const {

return q;

}

private:

int p;

int q;

};


const bool operator == (const Rational& lhs, const Rational& rhs)

{

if(

(lhs.Numerator() == rhs.Numerator()) &&

(lhs.Denominator() == rhs.Denominator())

)

return true;

else return false;

}

const bool operator > (const Rational& lhs, const Rational& rhs)

{

if(

(lhs.Numerator() * rhs.Denominator()) >

(lhs.Denominator() * rhs.Numerator())

)

return true;

else return false;

}

const bool operator < (const Rational& lhs, const Rational& rhs)

{

if(

(lhs.Numerator() * rhs.Denominator()) <

(lhs.Denominator() * rhs.Numerator())

)

return true;

else return false;

}


istream& operator >> (istream& stream, Rational& r)

{

int p_t, q_t;

stream >> p_t;

stream.ignore(1); //ignore '/'

stream >> q_t;

r.Initialize(p_t, q_t);

return stream;

}


ostream& operator << (ostream& stream, const Rational& r)

{

stream << r.Numerator() << '/' << r.Denominator();

return stream;

}


Rational operator + (const Rational& lhs, const Rational& rhs)

{

Rational result;

if(lhs.Denominator() == rhs.Denominator())

{

result.Initialize((lhs.Numerator() + rhs.Numerator()), rhs.Denominator());

}

else

{

result.Initialize(

(lhs.Numerator() * rhs.Denominator()) +

(lhs.Denominator() * rhs.Numerator()),

lhs.Denominator() * rhs.Denominator()

);

}

return result;

}

Rational operator - (const Rational& lhs, const Rational& rhs)

{

Rational result;

if(lhs.Denominator() == rhs.Denominator())

{

result.Initialize((lhs.Numerator() - rhs.Numerator()), rhs.Denominator());

}

else

{

result.Initialize(

(lhs.Numerator() * rhs.Denominator()) -

(lhs.Denominator() * rhs.Numerator()),

lhs.Denominator() * rhs.Denominator()

);

}

return result;

}


Rational operator * (const Rational& left, const Rational& right)

{

Rational result;

result.Initialize(

(right.Numerator() * left.Numerator()),

(right.Denominator() * left.Denominator())

);

return result;

}


Rational operator / (const Rational& left, const Rational& right)

{

if(right.Numerator() == 0)

{

throw domain_error("Division by zero");

}

else

{

Rational result;

result.Initialize(

(left.Numerator() * right.Denominator()),

(left.Denominator() * right.Numerator())

);

return result;

}

}


Rational GetRationalFromString(const string& s)

{

stringstream stream(s);

int numer;

int denom;

stream >> numer;

stream.ignore(1);

stream >> denom;

Rational result(numer, denom);

return result;

}


int main() {

string left;

string right;

char operation;

cin >> left >> operation >> right;


try

{

Rational first_operand = GetRationalFromString(left);

Rational second_operand = GetRationalFromString(right);

operation == '+' ? cout << first_operand + second_operand :

operation == '-' ? cout << first_operand - second_operand :

operation == '*' ? cout << first_operand * second_operand :

cout << first_operand / second_operand;

}

catch(exception& ex)

{

cout << ex.what();

}


getchar();

getchar();

return 0;

}

Так же в этом разделе:
 
MyTetra Share v.0.53
Яндекс индекс цитирования