Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // Created by Sailein on 03.05.2018.
- //
- #ifndef SAOKI_DIAMONDDOGS_H
- #define SAOKI_DIAMONDDOGS_H
- #include <iostream>
- #include <cstddef>
- #include <limits>
- #include <iomanip>
- #include <utility>
- #include <cmath>
- using namespace std;
- struct Complex
- {
- double re, im;
- Complex (double re = 0.0, double im = 0.0) : re(re), im(im) {} // constructor
- Complex (const Complex& other)
- {
- *this = other;
- }
- Complex operator+(const Complex& other) const // & - ссылка - чтобы не копировать
- {
- return Complex(re + other.re, im + other.im);
- }
- Complex operator*(const Complex& other) const
- {
- return Complex((re * other.re - im * other.im), (re * other.im + other.re * im));
- }
- Complex operator*(double scalar) const
- {
- return Complex(re * scalar, im * scalar);
- }
- const Complex& operator=(const Complex& other)
- {
- this->re = other.re;
- this->im = other.im;
- return *this;
- }
- double modulus () const
- {
- return sqrt(pow(re, 2.0) + pow(im, 2.0));
- }
- bool operator!= (const Complex& other) const
- {
- return (this->re != other.re) && (this->im != other.im);
- }
- bool operator== (const Complex& other) const
- {
- return (this->re == other.re) && (this->im == other.im);
- }
- bool operator<(double num) const
- {
- return modulus() < num;
- }
- bool operator>(double num) const
- {
- return modulus() > num;
- }
- };
- ostream& operator<<(ostream& os, const Complex& number)
- {
- return os << number.re << " + " << number.im << "i ";
- }
- istream& operator>>(istream& is, Complex& number)
- {
- return is >> number.re >> number.im;
- }
- template <typename T>
- class Condition // класс - интерфейс, содержит некотрую информацтю о функциях, которые не реализованы. тут у нас условине для recursiveCopy
- {
- public:
- virtual bool operator()(const T& data) const // Спецификатор virtual создаёт виртуальную функцию. Виртуальная функция — это член базового класса, который может быть переопределён производным классом.
- {
- return true;
- }
- };
- template <typename T>
- class WhereModInt1 : public Condition<T> // наследный класс - 1 условие для Where
- {
- public:
- virtual bool operator()(const T& data) const
- {
- return data % 3 == 1; //отстаток от деления на 3 равен 1 - конкретный случай
- }
- };
- template <typename T>
- class WhereModInt2 : public Condition<T> // наследный класс - 2 условие для Where
- {
- public:
- virtual bool operator()(const T& data) const
- {
- return data % 2 == 1; //отстаток от деления на 2 равен 1 - нечетные числа
- }
- };
- template <typename T>
- class WhereModInt3 : public Condition<T> // наследный класс - 3 условие для Where
- {
- public:
- virtual bool operator()(const T& data) const
- {
- return data % 5 == 0; //отстаток от деления на 2 равен 1 - нечетные числа
- }
- };
- template <typename T>
- class WhereModFloat1 : public Condition<T> // наследный класс - 1 условие для Where
- {
- public:
- virtual bool operator()(const T& data) const
- {
- return data == 1.0; //ток 1 возвращает
- }
- };
- template <typename T>
- class WhereModFloat2 : public Condition<T> // наследный класс - 2 условие для Where
- {
- public:
- virtual bool operator()(const T& data) const
- {
- return data == 2.0; //ток 2 возвращает
- }
- };
- template <typename T>
- class WhereModFloat3 : public Condition<T> // наследный класс - 3 условие для Where
- {
- public:
- virtual bool operator()(const T& data) const
- {
- return data != 5.0; //ток не 5 возвращает
- }
- };
- template <typename T>
- class WhereModComplex1 : public Condition<T> // наследный класс - 1 условие для Where
- {
- public:
- virtual bool operator()(const T& data) const
- {
- return data < 64.0; //модуль числа меньше 64
- }
- };
- template <typename T>
- class WhereModComplex2 : public Condition<T> // наследный класс - 2 условие для Where
- {
- public:
- virtual bool operator()(const T& data) const
- {
- return data > 4.0; //можудль числа больше 4
- }
- };
- template <typename T>
- class WhereModComplex3 : public Condition<T> // наследный класс - 3 условие для Where
- {
- public:
- virtual bool operator()(const T& data) const
- {
- return data < 1.0; //модуль числа меньше 1
- }
- };
- template <typename T>
- class Operation // класс - интерфейс , используется в редьюсе
- {
- public:
- virtual T operator()(const T& a, const T& b) const
- {
- return T();
- }
- };
- template <typename T>
- class Sum : public Operation<T> // 1 функция для reduce - сумма
- {
- public:
- virtual T operator()(const T& a, const T& b) const
- {
- return a + b;
- }
- };
- template <typename T>
- class Mul : public Operation<T> // 2 функция для reduce - произведение
- {
- public:
- virtual T operator()(const T& a, const T& b) const
- {
- return a * b;
- }
- };
- template <typename T> // шаблон класса стек
- class Stack // класс в котром реализован стек и его методы
- {
- protected: // модификатор доступа для производных данного класса
- class Node //производный класс - элемент стека
- {
- private:
- T m_data; //данные элемента (m = my)
- const Node* m_next; //указатель на след. элемент, const - квалификатор, который не дает поменять значения переменной.
- public:
- Node(const T& data, const Node* next = nullptr)
- : m_data(data), m_next(next) {};//конструктор элемента стека, после ":" список инициализации, nullptr - указаталь нулевой
- const T& data() const//метод класса - геттер данных
- {
- return m_data;
- }
- const Node* next() const // возвращает копию указателя геттер указателя
- {
- return m_next;
- }
- void setData (const T& data) // сеттер данных
- {
- m_data = data;
- }
- void setNext (const Node* next) //сеттер указателя на след элемент
- {
- m_next = next;
- }
- }; // подкласс "элемент стека" закончиося
- void updateSize () // измерение размера стека
- {
- for (const Node* node = m_head ;node != nullptr; node = node->next())
- {
- ++m_size;
- }
- }
- private:
- const Node* m_head = nullptr; //головной элемент
- size_t m_size = 0; //размер стека, в начале 0
- public:
- Stack<T> () {} //конструктор стека
- Stack<T> (const Stack<T>& other) // конструктор копирования
- {
- *this = other; // this - это наш стек, с которым идет работа
- }
- void push (const T& element) //пуш - добавление 1 элемента
- {
- m_head = new Node(element, m_head); //передвинули голову
- ++m_size; //увеличили размер
- }
- const T& top () const //показать головной элемент
- {
- return m_head->data();
- }
- void pop () //поп - убрать элемент
- {
- const Node* tmp = m_head; //решил вопрос через временный указатель
- m_head = m_head->next();
- delete tmp;
- --m_size;// уменьшить размер
- }
- ~Stack() // деструктор
- {
- while (!empty())
- {
- pop();
- }
- }
- bool empty() const // проверка на пустоту
- {
- return m_head == nullptr;
- }
- size_t size () const //вычисление размера
- {
- return m_size;
- }
- const Stack<T>& operator=(const Stack<T>& other) //оператор равно
- {
- m_head = recursiveCopy(other.m_head);
- m_size = other.m_size;
- return *this;
- }
- bool operator==(const Stack<T>& other)
- {
- return (this->size() == other.size()) && this->contains(other);
- }
- protected:
- const Node* recursiveCopy(const Node* node, const Condition<T>& condition = Condition<T>(), bool wanted = true) const // динамичекий полиморфизм - когда используем объект дочернего класса как объект базового класса
- {
- for (;(node != nullptr) && (condition(node->data()) != wanted); node = node->next()) {} // тут и юзаем оператор скобки!, когда не where - отрабатывает на всем
- if (node == nullptr) return nullptr;
- return new Node(node->data(), recursiveCopy(node->next(), condition, wanted));
- }
- public:
- friend ostream& operator<<(ostream& os, const Stack<T>& stack) //friend может в приват - печаталка
- {
- for (const Node* node = stack.m_head; node != nullptr; node = node->next())
- {
- os << node->data() << (node->next() == nullptr ? "" : ",");
- }
- if (stack.empty()) os << "stack is empty";
- return os;
- }
- Stack<T> where(const Condition<T>& condition) const //РАБОЧИЙ WHERE)) - вместо condition в мейне пилим один из трех where классов
- {
- Stack<T> result;
- result.m_head = recursiveCopy(this->m_head, condition);
- result.updateSize();
- return result;
- }
- T reduce(const Operation<T>& operation) const // Рабочий REDUCE - вместо operation ставится один из 3х редьюсов, в мейне
- {
- if (empty()) return T();
- T res = m_head->data();
- for (const Node* node = m_head->next(); node != nullptr; node = node->next())
- {
- res = operation (res, node->data());
- }
- return res;
- }
- size_t indexOf (const Stack<T>& sub) const
- {
- size_t index = 0;
- for (const Node* indexNode = m_head; indexNode != nullptr; indexNode = indexNode->next(), ++index) //индекс Головы подстека.
- {
- bool enter = true;
- for(const Node *node = indexNode, *subNode = sub.m_head; subNode != nullptr && node != nullptr; node = node->next(), subNode = subNode->next())
- {
- enter = enter && (node->data() == subNode->data()) && !((node->next() == nullptr) && (subNode->next() != nullptr));
- }
- if (enter) return index;
- }
- return numeric_limits<size_t>::max(); // максимуим от size_t :: - вызов статического метода. а если индекс не найден - то вернет ЭТО вот "4294967295"
- }
- bool contains (const Stack<T>& sub) const // проверяет входит ли у нас элемент в стек или нет. Вспомогательная ф-я, для Вас, Андрей Владимирович
- {
- return indexOf(sub) != numeric_limits<size_t>::max();
- }
- pair<Stack<T>, Stack<T>> split (const Condition<T>& condition) const
- {
- pair<Stack<T>, Stack<T>> res;
- res.first.m_head = recursiveCopy(this->m_head, condition);
- res.second.m_head = recursiveCopy(this->m_head, condition, false);
- res.first.updateSize();
- res.second.updateSize();
- return res;
- }
- };
- void testWhereInt1();
- void testWhereInt2();
- void testWhereInt3();
- void testWhereFloat1();
- void testWhereFloat2();
- void testWhereFloat3();
- void testWhereComplex1();
- void testWhereComplex2();
- void testWhereComplex3();
- void testReduceInt1();
- void testReduceInt2();
- void testReduceFloat1();
- void testReduceFloat2();
- void testReduceComplex1();
- void testReduceComplex2();
- void testIndexOfInt();
- void testIndexOfFloat();
- void testIndexOfComplex();
- void testSplitInt();
- void testSplitFloat();
- void testSplitComplex();
- void testAll();
- #endif //SAOKI_DIAMONDDOGS_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement