Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <iostream>
- #include <vector>
- using namespace std;
- template<typename T>
- vector<T> operator+(vector<T> &a, vector<T> &b) { // перегрузили оператор для векторов, чтобы сложить их
- vector<T> res;
- res = a;
- for (auto i : b) {
- res.push_back(i);
- }
- return res;
- }
- class Fraction { // класс дробь
- private:
- vector<unsigned char> wholePart, fractionPart; // целая часть, дробная
- bool sign; // знак
- template<typename T>
- static void f(vector<T> &a, vector<T> &b) { // эта функция нужна, чтобы избежать копирование кода
- while (a.size() < b.size()) {
- a.push_back('0');
- }
- }
- static pair<vector<unsigned char>, vector<unsigned char>> getTwo(const Fraction &_a, const Fraction &_b) { // это функция переводит дробь в массив, чтобы работать с ним дальше
- auto a_f = _a.fractionPart;
- auto b_f = _b.fractionPart;
- auto a_w = _a.wholePart;
- auto b_w = _b.wholePart;
- f(a_f, b_f);
- f(b_f, a_f);
- f(a_w, b_w);
- f(b_w, a_w);
- reverse(a_f.begin(), a_f.end());
- reverse(b_f.begin(), b_f.end());
- auto a = a_f + a_w;
- auto b = b_f + b_w;
- return {a, b};
- }
- static vector<unsigned char> summary(const Fraction &_a, const Fraction &_b) { // суммирование дробей
- vector<unsigned char> a, b;
- auto twoMas = getTwo(_a, _b);
- a = twoMas.first;
- b = twoMas.second;
- size_t mx = a.size();
- vector<int> res(mx + 1, 0);
- for (int i = 0; i < mx; i++) {
- res[i] += int(a[i] - '0') + int(b[i] - '0');
- res[i + 1] += res[i] / 10;
- res[i] %= 10;
- }
- vector<unsigned char> r;
- for (int re = 0; re <= mx; ++re) {
- r.push_back(res[re] + '0');
- }
- return r;
- }
- static vector<unsigned char> pr(const Fraction &_a, const Fraction &_b) { // произведение дробей
- vector<unsigned char> a, b;
- auto twoMas = getTwo(_a, _b);
- a = twoMas.first;
- b = twoMas.second;
- size_t mx = a.size();
- vector<int> v(2 * mx + 1, 0);
- int cnt = 0;
- for (unsigned char i : a) {
- int k = cnt;
- for (unsigned char j : b) {
- v[k] += (i - '0') * (j - '0') % 10;
- v[k + 1] += (i - '0') * (j - '0') / 10 + v[k] / 10;
- v[k] %= 10;
- k++;
- }
- cnt++;
- }
- vector<unsigned char> s;
- for (int i : v)s.push_back(i + '0');
- return s;
- }
- static vector<unsigned char> sub(const Fraction &_a, const Fraction &_b) { // вычитание дробей
- auto a_f = _a.fractionPart;
- auto b_f = _b.fractionPart;
- auto a_w = _a.wholePart;
- auto b_w = _b.wholePart;
- f(a_f, b_f);
- f(b_f, a_f);
- f(a_w, b_w);
- f(b_w, a_w);
- if (abs(_a) < abs(_b)) {
- swap(a_f, b_f);
- swap(a_w, b_w);
- }
- reverse(a_f.begin(), a_f.end());
- reverse(b_f.begin(), b_f.end());
- size_t mx = max(a_f.size(), b_f.size()) + max(b_w.size(), a_w.size());
- auto a = a_f + a_w;
- auto b = b_f + b_w;
- vector<int> res(mx + 1, 0);
- for (int i = 0; i < mx; i++) {
- if (a[i] < b[i]) {
- a[i + 1]--;
- a[i] += 10;
- }
- res[i] = a[i] - b[i];
- }
- vector<unsigned char> r;
- for (int re = 0; re <= mx; ++re) {
- r.push_back(res[re] + '0');
- }
- return r;
- }
- static Fraction getFraction(vector<unsigned char> &res, int divide, bool sign) { // эта функция получения дроби, используется в операторах
- vector<unsigned char> wh, fr;
- for (int i = 0; i < divide; ++i) {
- fr.push_back(res[i]);
- }
- for (int i = divide; i < res.size(); ++i) {
- wh.push_back(res[i]);
- }
- reverse(fr.begin(), fr.end());
- while (!fr.empty() && fr.back() == '0')fr.pop_back();
- while (!wh.empty() && wh.back() == '0')wh.pop_back();
- reverse(wh.begin(), wh.end());
- Fraction result = Fraction(wh, fr, sign);
- return result;
- }
- public:
- Fraction() { // пустой конструктор
- wholePart = {};
- fractionPart = {};
- sign = false;
- }
- Fraction(vector<unsigned char> &_w, vector<unsigned char> &_f, unsigned char _s) { // 1 вид конструктора
- reverse(_w.begin(), _w.end());
- wholePart = _w;
- fractionPart = _f;
- if (_s == '-')
- sign = true;
- else {
- sign = false;
- }
- }
- Fraction(vector<unsigned char> &_w, vector<unsigned char> &_f, bool _s) { // 2 вид конструктора
- reverse(_w.begin(), _w.end());
- wholePart = _w;
- fractionPart = _f;
- sign = _s;
- }
- friend bool operator==(const Fraction &a, const Fraction &b) { // оператор ставнения
- return a.fractionPart == b.fractionPart && a.wholePart == b.wholePart && a.sign == b.sign;
- }
- friend bool operator!=(const Fraction &a, const Fraction &b) { // оператор не равно
- return !(a == b);
- }
- friend bool operator<(const Fraction &a, const Fraction &b) { // оператор меньше
- if (a.sign && !b.sign) {
- return true;
- }
- if (!a.sign && b.sign) {
- return false;
- }
- if (a.wholePart.size() != b.wholePart.size()) {
- if (a.sign) {
- return a.wholePart.size() >= b.wholePart.size();
- } else {
- return a.wholePart.size() < b.wholePart.size();
- }
- } else if (a.wholePart != b.wholePart) {
- int _size = a.wholePart.size();
- for (int i = _size - 1; i >= 0; --i) {
- if (a.wholePart[i] != b.wholePart[i]) {
- if (a.sign) {
- return a.wholePart[i] >= b.wholePart[i];
- } else {
- return a.wholePart[i] < b.wholePart[i];
- }
- }
- }
- } else {
- for (int i = 0; i < min(a.fractionPart.size(), b.fractionPart.size()); ++i) {
- if (a.fractionPart[i] != b.fractionPart[i]) {
- if (a.sign) {
- return a.fractionPart[i] >= b.fractionPart[i];
- } else {
- return a.fractionPart[i] < b.fractionPart[i];
- }
- }
- }
- if (a.sign) {
- return a.fractionPart.size() >= b.fractionPart.size();
- } else {
- return a.fractionPart.size() < b.fractionPart.size();
- }
- }
- }
- friend bool operator>(const Fraction &a, const Fraction &b) { // оператор больше
- return !(a < b);
- }
- friend Fraction operator-(const Fraction &a, const Fraction &b) { // оператор -
- if (a.sign == b.sign) {
- auto res = sub(a, b);
- int divide = max(a.fractionPart.size(), b.fractionPart.size());
- bool _sign = (a.sign) ? !(a > b) : a < b;
- return getFraction(res, divide, _sign);
- } else {
- auto res = summary(a, b);
- int divide = max(a.fractionPart.size(), b.fractionPart.size());
- return getFraction(res, divide, a.sign);
- }
- }
- friend Fraction operator+(const Fraction &a, const Fraction &b) { // оператор +
- if (a.sign == b.sign) {
- auto res = summary(a, b);
- int divide = max(a.fractionPart.size(), b.fractionPart.size());
- return getFraction(res, divide, a.sign);
- } else {
- auto res = sub(a, b);
- bool _sign = (abs(a) < abs(b) ? b.sign : a.sign);
- int divide = max(a.fractionPart.size(), b.fractionPart.size());
- return getFraction(res, divide, _sign);
- }
- }
- friend Fraction operator*(const Fraction &a, const Fraction &b) { // оператор *
- auto res = pr(a, b);
- int divide = max(a.fractionPart.size(), b.fractionPart.size());
- bool _sign = a.sign != b.sign;
- return getFraction(res, divide, _sign);
- }
- static Fraction abs(const Fraction &a) { // функция модуль
- auto _a = a;
- _a.sign = false;
- return _a;
- }
- void print() { // чтобы вывести дробь
- if (this->sign) {
- cout << "-";
- }
- for (size_t i = this->wholePart.size(); i > 0; --i) {
- cout << this->wholePart[i - 1];
- }
- if (this->wholePart.empty()) {
- cout << "0";
- }
- if (!this->fractionPart.empty()) {
- cout << ".";
- }
- for (unsigned char i : this->fractionPart) {
- cout << i;
- }
- }
- };
- int main() {
- vector<unsigned char> wh, fr;
- wh = {'6'};
- Fraction a = Fraction(wh, fr, false);
- wh = {'7', '1', '1'};
- Fraction b = Fraction(wh, fr, false);
- b.print();
- auto c = a * b;
- cout << "\n";
- c.print();
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement