Advertisement
NickAndNick

class Fraction

Sep 18th, 2021
676
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <iostream>
  2. #include <string>
  3. #include <sstream>
  4.  
  5. using namespace std;
  6.  
  7. class Fraction {
  8. public:
  9.     using inner_type = long long;
  10.     Fraction() : val({ 0, 1 }) {}
  11.     Fraction(const string& str) {
  12.         val = split(str, '/');
  13.         normalize();
  14.     }
  15.     string value()const {
  16.         return to_string(val.first) + '/' + to_string(val.second);
  17.     }
  18.     Fraction absolute()const {
  19.         return Fraction(abs(val.first), val.second);
  20.     }
  21.     Fraction& operator-() {
  22.         val.first *= -1;
  23.         return *this;
  24.     }
  25.     bool corrupt()const {
  26.         return val.second == 0;
  27.     }
  28. private:
  29.     pair<inner_type, inner_type> val;
  30.     Fraction(inner_type a, inner_type b) : val{ a, b } {
  31.         normalize();
  32.     }
  33.     void normalize() {
  34.         auto x = gcd(val);
  35.         if (x) {
  36.             val.first /= x;
  37.             val.second /= x;
  38.             if (val.second < 0) {
  39.                 val.first *= -1;
  40.                 val.second *= -1;
  41.             }
  42.         }
  43.     }
  44.     inner_type gcd(pair<inner_type, inner_type> v) {
  45.         if (v.second) {
  46.             v.first = abs(v.first);
  47.             if (v.first) {
  48.                 v.second = abs(v.second);
  49.                 while (v.first != v.second) {
  50.                     if (v.first > v.second) swap(v.first, v.second);
  51.                     v.second -= v.first;
  52.                 }
  53.             }
  54.         }
  55.         return v.first;
  56.     }
  57.     pair<inner_type, inner_type> split(const string& str, char delim) {
  58.         pair<inner_type, inner_type> box;
  59.         stringstream ss(str);
  60.         try {
  61.             string token;
  62.             getline(ss, token, delim);
  63.             box.first = stoll(token);
  64.             getline(ss, token);
  65.             box.second = stoll(token);
  66.         } catch (...) {
  67.             box.second = 0;
  68.             ss.clear();
  69.             ss.ignore(ss.rdbuf()->in_avail());
  70.         }
  71.         return box;
  72.     }
  73.     friend Fraction operator-(const Fraction& a, const Fraction& b) {
  74.         const auto an = a.val.first * b.val.second;
  75.         const auto bn = b.val.first * a.val.second;
  76.         const auto abn = an - bn;
  77.         const auto abd = a.val.second * b.val.second;
  78.         return Fraction(to_string(abn) + '/' + to_string(abd));
  79.     }
  80.     friend bool operator<(const Fraction& a, const Fraction& b) {
  81.         return double(a.val.first) / a.val.second < double(b.val.first) / b.val.second;
  82.     }
  83.     friend bool operator<(const Fraction& a, const double b) {
  84.         return double(a.val.first) / a.val.second < b;
  85.     }
  86.     friend bool operator<(const double a, const Fraction& b) {
  87.         return a < double(b.val.first) / b.val.second;
  88.     }
  89.     friend bool operator==(const Fraction& a, const Fraction& b) {
  90.         return a.val.first == b.val.first && a.val.second == b.val.second;
  91.     }
  92.     friend bool operator==(const Fraction& a, const double b) {
  93.         return double(a.val.first) / a.val.second == b;
  94.     }
  95.     friend bool operator>(const Fraction& a, const Fraction& b) {
  96.         return double(a.val.first) / a.val.second > double(b.val.first) / b.val.second;
  97.     }
  98.     friend bool operator>(const Fraction& a, const double b) {
  99.         return double(a.val.first) / a.val.second > b;
  100.     }
  101.     friend Fraction operator%(const Fraction& a, const Fraction& b) {
  102.         auto xa = a.absolute();
  103.         auto xb = b.absolute();
  104.         if (xa < xb) return a;
  105.         auto x = xa - xb;
  106.         if (x == 0) return Fraction(0, 1);
  107.         while (x > xb) x = x - xb;
  108.         return a.val.first > 0 ? x : -x;
  109.     }
  110.     friend Fraction operator%(const inner_type a, const Fraction& b) {
  111.         Fraction x(a, 1);
  112.         return operator%(x, b);
  113.     }
  114.     friend Fraction operator*(const Fraction& a, const inner_type b) {
  115.         return Fraction(a.val.first * b, a.val.second);
  116.     }
  117.     friend Fraction operator*(const inner_type a, const Fraction& b) {
  118.         return Fraction(b.val.first * a, b.val.second);
  119.     }
  120.     friend Fraction operator*(const Fraction& a, const Fraction& b) {
  121.         return Fraction(a.val.first * b.val.first, a.val.second * b.val.second);
  122.     }
  123.     friend Fraction operator/(const Fraction& a, const Fraction& b) {
  124.         return Fraction(a.val.first * b.val.second, a.val.second * b.val.first);
  125.     }
  126.     friend Fraction operator+(const Fraction& a, const Fraction& b) {
  127.         auto d = a.val.second * b.val.second;
  128.         auto n = a.val.first * b.val.second + b.val.first * a.val.second;
  129.         return Fraction(n, d);
  130.     }
  131.     friend Fraction operator+(const Fraction& a, const inner_type b) {
  132.         auto d = a.val.second;
  133.         auto n = a.val.first + b * a.val.second;
  134.         return Fraction(n, d);
  135.     }
  136.     friend Fraction operator+(const inner_type b, const Fraction& a) {
  137.         auto d = a.val.second;
  138.         auto n = a.val.first + b * a.val.second;
  139.         return Fraction(n, d);
  140.     }
  141.     friend ostream& operator<<(ostream& out, const Fraction& fr) {
  142.         return out << fr.val.first << '/' << fr.val.second;
  143.     }
  144.     friend istream& operator>>(istream& inp, Fraction& fr) {
  145.         string str;
  146.         inp >> str;
  147.         fr.val = fr.split(str, '/');
  148.         fr.normalize();
  149.         return inp;
  150.     }
  151. };
  152.  
  153. Fraction fraction(const string& msg) {
  154.     Fraction value;
  155.     do {
  156.         cout << "Введите " << msg;
  157.         if (!msg.empty()) cout.put(' ');
  158.         cout << "(дробь в формате x/y): ";
  159.         cin >> value;
  160.         cin.ignore(cin.rdbuf()->in_avail());
  161.     } while (value.corrupt());
  162.     return value;
  163. }
  164.  
  165. int main() {
  166.     system("chcp 1251 > nul");
  167.     auto a = fraction("первую");
  168.     auto b = fraction("вторую");
  169.     char operation;
  170.     auto repeat = true;
  171.     do {
  172.         cout << "Введите арифметическую операцию [ + - * / % ]: ";
  173.         operation = cin.get();
  174.         cin.ignore(cin.rdbuf()->in_avail());
  175.         Fraction result;
  176.         switch (operation) {
  177.             case '+': result = a + b; break;
  178.             case '-': result = a - b; break;
  179.             case '/': result = a / b; break;
  180.             case '*': result = a * b; break;
  181.             case '%': result = a % b; break;
  182.             default: repeat = false;
  183.         }
  184.         if (repeat) {
  185.             cout
  186.                 << a << ' ' << operation << ' '
  187.                 << b << " = " << result << '\n';
  188.         }
  189.        
  190.     } while (repeat);
  191. }
Advertisement
RAW Paste Data Copied
Advertisement