Advertisement
georgiy110802

Class Fraction

May 27th, 2021 (edited)
706
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.57 KB | None | 0 0
  1. #include <algorithm>
  2. #include <iostream>
  3. #include <vector>
  4.  
  5. using namespace std;
  6.  
  7. template<typename T>
  8. vector<T> operator+(vector<T> &a, vector<T> &b) { // перегрузили оператор для векторов, чтобы сложить их
  9.     vector<T> res;
  10.     res = a;
  11.     for (auto i : b) {
  12.         res.push_back(i);
  13.     }
  14.     return res;
  15. }
  16.  
  17. class Fraction { // класс дробь
  18. private:
  19.     vector<unsigned char> wholePart, fractionPart; // целая часть, дробная
  20.     bool sign; // знак
  21.  
  22.     template<typename T>
  23.     static void f(vector<T> &a, vector<T> &b) { // эта функция нужна, чтобы избежать копирование кода
  24.         while (a.size() < b.size()) {
  25.             a.push_back('0');
  26.         }
  27.     }
  28.  
  29.     static pair<vector<unsigned char>, vector<unsigned char>> getTwo(const Fraction &_a, const Fraction &_b) { // это функция переводит дробь в массив, чтобы работать с ним дальше
  30.         auto a_f = _a.fractionPart;
  31.         auto b_f = _b.fractionPart;
  32.         auto a_w = _a.wholePart;
  33.         auto b_w = _b.wholePart;
  34.         f(a_f, b_f);
  35.         f(b_f, a_f);
  36.         f(a_w, b_w);
  37.         f(b_w, a_w);
  38.         reverse(a_f.begin(), a_f.end());
  39.         reverse(b_f.begin(), b_f.end());
  40.         auto a = a_f + a_w;
  41.         auto b = b_f + b_w;
  42.         return {a, b};
  43.     }
  44.  
  45.     static vector<unsigned char> summary(const Fraction &_a, const Fraction &_b) { // суммирование дробей
  46.         vector<unsigned char> a, b;
  47.         auto twoMas = getTwo(_a, _b);
  48.         a = twoMas.first;
  49.         b = twoMas.second;
  50.         size_t mx = a.size();
  51.         vector<int> res(mx + 1, 0);
  52.         for (int i = 0; i < mx; i++) {
  53.             res[i] += int(a[i] - '0') + int(b[i] - '0');
  54.             res[i + 1] += res[i] / 10;
  55.             res[i] %= 10;
  56.         }
  57.         vector<unsigned char> r;
  58.         for (int re = 0; re <= mx; ++re) {
  59.             r.push_back(res[re] + '0');
  60.         }
  61.         return r;
  62.     }
  63.  
  64.     static vector<unsigned char> pr(const Fraction &_a, const Fraction &_b) { // произведение дробей
  65.         vector<unsigned char> a, b;
  66.         auto twoMas = getTwo(_a, _b);
  67.         a = twoMas.first;
  68.         b = twoMas.second;
  69.         size_t mx = a.size();
  70.         vector<int> v(2 * mx + 1, 0);
  71.         int cnt = 0;
  72.         for (unsigned char i : a) {
  73.             int k = cnt;
  74.             for (unsigned char j : b) {
  75.                 v[k] += (i - '0') * (j - '0') % 10;
  76.                 v[k + 1] += (i - '0') * (j - '0') / 10 + v[k] / 10;
  77.                 v[k] %= 10;
  78.                 k++;
  79.             }
  80.             cnt++;
  81.         }
  82.         vector<unsigned char> s;
  83.         for (int i : v)s.push_back(i + '0');
  84.         return s;
  85.     }
  86.  
  87.     static vector<unsigned char> sub(const Fraction &_a, const Fraction &_b) { // вычитание дробей
  88.         auto a_f = _a.fractionPart;
  89.         auto b_f = _b.fractionPart;
  90.         auto a_w = _a.wholePart;
  91.         auto b_w = _b.wholePart;
  92.         f(a_f, b_f);
  93.         f(b_f, a_f);
  94.         f(a_w, b_w);
  95.         f(b_w, a_w);
  96.         if (abs(_a) < abs(_b)) {
  97.             swap(a_f, b_f);
  98.             swap(a_w, b_w);
  99.         }
  100.         reverse(a_f.begin(), a_f.end());
  101.         reverse(b_f.begin(), b_f.end());
  102.         size_t mx = max(a_f.size(), b_f.size()) + max(b_w.size(), a_w.size());
  103.         auto a = a_f + a_w;
  104.         auto b = b_f + b_w;
  105.         vector<int> res(mx + 1, 0);
  106.         for (int i = 0; i < mx; i++) {
  107.             if (a[i] < b[i]) {
  108.                 a[i + 1]--;
  109.                 a[i] += 10;
  110.             }
  111.             res[i] = a[i] - b[i];
  112.         }
  113.         vector<unsigned char> r;
  114.         for (int re = 0; re <= mx; ++re) {
  115.             r.push_back(res[re] + '0');
  116.         }
  117.         return r;
  118.     }
  119.  
  120.     static Fraction getFraction(vector<unsigned char> &res, int divide, bool sign) { // эта функция получения дроби, используется в операторах
  121.         vector<unsigned char> wh, fr;
  122.         for (int i = 0; i < divide; ++i) {
  123.             fr.push_back(res[i]);
  124.         }
  125.         for (int i = divide; i < res.size(); ++i) {
  126.             wh.push_back(res[i]);
  127.         }
  128.         reverse(fr.begin(), fr.end());
  129.         while (!fr.empty() && fr.back() == '0')fr.pop_back();
  130.         while (!wh.empty() && wh.back() == '0')wh.pop_back();
  131.         reverse(wh.begin(), wh.end());
  132.         Fraction result = Fraction(wh, fr, sign);
  133.         return result;
  134.     }
  135.  
  136. public:
  137.     Fraction() { // пустой конструктор
  138.         wholePart = {};
  139.         fractionPart = {};
  140.         sign = false;
  141.     }
  142.  
  143.     Fraction(vector<unsigned char> &_w, vector<unsigned char> &_f, unsigned char _s) { // 1 вид конструктора
  144.         reverse(_w.begin(), _w.end());
  145.         wholePart = _w;
  146.         fractionPart = _f;
  147.         if (_s == '-')
  148.             sign = true;
  149.         else {
  150.             sign = false;
  151.         }
  152.     }
  153.  
  154.     Fraction(vector<unsigned char> &_w, vector<unsigned char> &_f, bool _s) { // 2 вид конструктора
  155.         reverse(_w.begin(), _w.end());
  156.         wholePart = _w;
  157.         fractionPart = _f;
  158.         sign = _s;
  159.     }
  160.  
  161.     friend bool operator==(const Fraction &a, const Fraction &b) { // оператор ставнения
  162.         return a.fractionPart == b.fractionPart && a.wholePart == b.wholePart && a.sign == b.sign;
  163.     }
  164.  
  165.     friend bool operator!=(const Fraction &a, const Fraction &b) { // оператор не равно
  166.         return !(a == b);
  167.     }
  168.  
  169.     friend bool operator<(const Fraction &a, const Fraction &b) { // оператор меньше
  170.         if (a.sign && !b.sign) {
  171.             return true;
  172.         }
  173.         if (!a.sign && b.sign) {
  174.             return false;
  175.         }
  176.         if (a.wholePart.size() != b.wholePart.size()) {
  177.             if (a.sign) {
  178.                 return a.wholePart.size() >= b.wholePart.size();
  179.             } else {
  180.                 return a.wholePart.size() < b.wholePart.size();
  181.             }
  182.         } else if (a.wholePart != b.wholePart) {
  183.             int _size = a.wholePart.size();
  184.             for (int i = _size - 1; i >= 0; --i) {
  185.                 if (a.wholePart[i] != b.wholePart[i]) {
  186.                     if (a.sign) {
  187.                         return a.wholePart[i] >= b.wholePart[i];
  188.                     } else {
  189.                         return a.wholePart[i] < b.wholePart[i];
  190.                     }
  191.                 }
  192.             }
  193.         } else {
  194.             for (int i = 0; i < min(a.fractionPart.size(), b.fractionPart.size()); ++i) {
  195.                 if (a.fractionPart[i] != b.fractionPart[i]) {
  196.                     if (a.sign) {
  197.                         return a.fractionPart[i] >= b.fractionPart[i];
  198.                     } else {
  199.                         return a.fractionPart[i] < b.fractionPart[i];
  200.                     }
  201.                 }
  202.             }
  203.             if (a.sign) {
  204.                 return a.fractionPart.size() >= b.fractionPart.size();
  205.             } else {
  206.                 return a.fractionPart.size() < b.fractionPart.size();
  207.             }
  208.         }
  209.     }
  210.  
  211.     friend bool operator>(const Fraction &a, const Fraction &b) { // оператор больше
  212.         return !(a < b);
  213.     }
  214.  
  215.     friend Fraction operator-(const Fraction &a, const Fraction &b) { // оператор -
  216.         if (a.sign == b.sign) {
  217.             auto res = sub(a, b);
  218.             int divide = max(a.fractionPart.size(), b.fractionPart.size());
  219.             bool _sign = (a.sign) ? !(a > b) : a < b;
  220.             return getFraction(res, divide, _sign);
  221.         } else {
  222.             auto res = summary(a, b);
  223.             int divide = max(a.fractionPart.size(), b.fractionPart.size());
  224.             return getFraction(res, divide, a.sign);
  225.         }
  226.     }
  227.  
  228.     friend Fraction operator+(const Fraction &a, const Fraction &b) { // оператор +
  229.         if (a.sign == b.sign) {
  230.             auto res = summary(a, b);
  231.             int divide = max(a.fractionPart.size(), b.fractionPart.size());
  232.             return getFraction(res, divide, a.sign);
  233.         } else {
  234.             auto res = sub(a, b);
  235.             bool _sign = (abs(a) < abs(b) ? b.sign : a.sign);
  236.             int divide = max(a.fractionPart.size(), b.fractionPart.size());
  237.             return getFraction(res, divide, _sign);
  238.         }
  239.     }
  240.  
  241.     friend Fraction operator*(const Fraction &a, const Fraction &b) { // оператор *
  242.         auto res = pr(a, b);
  243.         int divide = max(a.fractionPart.size(), b.fractionPart.size());
  244.         bool _sign = a.sign != b.sign;
  245.         return getFraction(res, divide, _sign);
  246.     }
  247.  
  248.     static Fraction abs(const Fraction &a) { // функция модуль
  249.         auto _a = a;
  250.         _a.sign = false;
  251.         return _a;
  252.     }
  253.  
  254.     void print() { // чтобы вывести дробь
  255.         if (this->sign) {
  256.             cout << "-";
  257.         }
  258.         for (size_t i = this->wholePart.size(); i > 0; --i) {
  259.             cout << this->wholePart[i - 1];
  260.         }
  261.         if (this->wholePart.empty()) {
  262.             cout << "0";
  263.         }
  264.         if (!this->fractionPart.empty()) {
  265.             cout << ".";
  266.         }
  267.         for (unsigned char i : this->fractionPart) {
  268.             cout << i;
  269.         }
  270.     }
  271. };
  272.  
  273.  
  274. int main() {
  275.     vector<unsigned char> wh, fr;
  276.     wh = {'6'};
  277.     Fraction a = Fraction(wh, fr, false);
  278.     wh = {'7', '1', '1'};
  279.     Fraction b = Fraction(wh, fr, false);
  280.     b.print();
  281.     auto c = a * b;
  282.     cout << "\n";
  283.     c.print();
  284. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement