Advertisement
Sailein

stackProg2

Apr 27th, 2018
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.96 KB | None | 0 0
  1. //
  2. // Created by Sailein on 03.05.2018.
  3. //
  4.  
  5. #ifndef SAOKI_DIAMONDDOGS_H
  6. #define SAOKI_DIAMONDDOGS_H
  7. #include <iostream>
  8. #include <cstddef>
  9. #include <limits>
  10. #include <iomanip>
  11. #include <utility>
  12. #include <cmath>
  13. using namespace std;
  14.  
  15. struct Complex
  16. {
  17.     double re, im;
  18.     Complex (double re = 0.0, double im = 0.0) : re(re), im(im) {} // constructor
  19.     Complex (const Complex& other)
  20.     {
  21.         *this = other;
  22.     }
  23.     Complex operator+(const Complex& other) const // & - ссылка - чтобы не копировать
  24.     {
  25.         return Complex(re + other.re, im + other.im);
  26.     }
  27.     Complex operator*(const Complex& other) const
  28.     {
  29.         return Complex((re * other.re - im * other.im), (re * other.im + other.re * im));
  30.     }
  31.     Complex operator*(double scalar) const
  32.     {
  33.         return Complex(re * scalar, im * scalar);
  34.     }
  35.     const Complex& operator=(const Complex& other)
  36.     {
  37.         this->re = other.re;
  38.         this->im = other.im;
  39.         return *this;
  40.     }
  41.     double modulus () const
  42.     {
  43.         return sqrt(pow(re, 2.0) + pow(im, 2.0));
  44.     }
  45.     bool operator!= (const Complex& other) const
  46.     {
  47.         return (this->re != other.re) && (this->im != other.im);
  48.     }
  49.     bool operator== (const Complex& other) const
  50.     {
  51.         return (this->re == other.re) && (this->im == other.im);
  52.     }
  53.     bool operator<(double num) const
  54.     {
  55.         return modulus() < num;
  56.     }
  57.     bool operator>(double num) const
  58.     {
  59.         return modulus() > num;
  60.     }
  61. };
  62.  
  63. ostream& operator<<(ostream& os, const Complex& number)
  64. {
  65.     return os << number.re << " + " << number.im << "i ";
  66. }
  67.  
  68. istream& operator>>(istream& is, Complex& number)
  69. {
  70.     return is >> number.re >> number.im;
  71. }
  72.  
  73. template <typename T>
  74. class Condition // класс - интерфейс, содержит некотрую информацтю о функциях, которые не реализованы. тут у нас условине для recursiveCopy
  75. {
  76. public:
  77.     virtual bool operator()(const T& data) const // Спецификатор virtual создаёт виртуальную функцию. Виртуальная функция — это член базового класса, который может быть переопределён производным классом.
  78.     {
  79.         return true;
  80.     }
  81. };
  82.  
  83. template <typename T>
  84. class WhereModInt1 : public Condition<T> // наследный класс - 1 условие для Where
  85. {
  86. public:
  87.     virtual bool operator()(const T& data) const
  88.     {
  89.         return data % 3 == 1; //отстаток от деления на 3 равен 1 - конкретный случай
  90.     }
  91. };
  92.  
  93. template <typename T>
  94. class WhereModInt2 : public Condition<T> // наследный класс - 2 условие для Where
  95. {
  96. public:
  97.     virtual bool operator()(const T& data) const
  98.     {
  99.         return data % 2 == 1; //отстаток от деления на 2 равен 1 - нечетные числа
  100.     }
  101. };
  102.  
  103. template <typename T>
  104. class WhereModInt3 : public Condition<T> // наследный класс - 3 условие для Where
  105. {
  106. public:
  107.     virtual bool operator()(const T& data) const
  108.     {
  109.         return data % 5 == 0; //отстаток от деления на 2 равен 1 - нечетные числа
  110.     }
  111. };
  112.  
  113. template <typename T>
  114. class WhereModFloat1 : public Condition<T> // наследный класс - 1 условие для Where
  115. {
  116. public:
  117.     virtual bool operator()(const T& data) const
  118.     {
  119.         return data == 1.0; //ток 1 возвращает
  120.     }
  121. };
  122.  
  123. template <typename T>
  124. class WhereModFloat2 : public Condition<T> // наследный класс - 2 условие для Where
  125. {
  126. public:
  127.     virtual bool operator()(const T& data) const
  128.     {
  129.         return data == 2.0; //ток 2 возвращает
  130.     }
  131. };
  132.  
  133. template <typename T>
  134. class WhereModFloat3 : public Condition<T> // наследный класс - 3 условие для Where
  135. {
  136. public:
  137.     virtual bool operator()(const T& data) const
  138.     {
  139.         return data != 5.0; //ток  не  5 возвращает
  140.     }
  141. };
  142.  
  143. template <typename T>
  144. class WhereModComplex1 : public Condition<T> // наследный класс - 1 условие для Where
  145. {
  146. public:
  147.     virtual bool operator()(const T& data) const
  148.     {
  149.         return data < 64.0; //модуль числа меньше 64
  150.     }
  151. };
  152.  
  153. template <typename T>
  154. class WhereModComplex2 : public Condition<T> // наследный класс - 2 условие для Where
  155. {
  156. public:
  157.     virtual bool operator()(const T& data) const
  158.     {
  159.         return data > 4.0; //можудль числа больше 4
  160.     }
  161. };
  162.  
  163. template <typename T>
  164. class WhereModComplex3 : public Condition<T> // наследный класс - 3 условие для Where
  165. {
  166. public:
  167.     virtual bool operator()(const T& data) const
  168.     {
  169.         return data < 1.0; //модуль числа  меньше 1
  170.     }
  171. };
  172.  
  173. template <typename T>
  174. class Operation // класс - интерфейс , используется в редьюсе
  175. {
  176. public:
  177.     virtual T operator()(const T& a, const T& b) const
  178.     {
  179.         return T();
  180.     }
  181. };
  182.  
  183. template <typename T>
  184. class Sum : public Operation<T> // 1 функция для reduce - сумма
  185. {
  186. public:
  187.     virtual T operator()(const T& a, const T& b) const
  188.     {
  189.         return a + b;
  190.     }
  191. };
  192.  
  193. template <typename T>
  194. class Mul : public Operation<T> // 2 функция для reduce - произведение
  195. {
  196. public:
  197.     virtual T operator()(const T& a, const T& b) const
  198.     {
  199.         return a * b;
  200.     }
  201. };
  202.  
  203. template <typename T> // шаблон класса стек
  204. class Stack // класс в котром реализован стек и его методы
  205. {
  206. protected: // модификатор доступа для производных данного класса
  207.     class Node //производный класс - элемент стека
  208.     {
  209.     private:
  210.         T m_data; //данные элемента (m = my)
  211.         const Node* m_next; //указатель на след. элемент, const - квалификатор, который не дает поменять значения переменной.
  212.     public:
  213.         Node(const T& data, const Node* next = nullptr)
  214.                 : m_data(data), m_next(next) {};//конструктор элемента стека, после ":" список инициализации, nullptr - указаталь нулевой
  215.         const T& data() const//метод класса - геттер данных
  216.         {
  217.             return m_data;
  218.         }
  219.         const Node* next() const // возвращает копию указателя геттер указателя
  220.         {
  221.             return m_next;
  222.         }
  223.         void setData (const T& data) // сеттер данных
  224.         {
  225.             m_data = data;
  226.         }
  227.         void setNext (const Node* next) //сеттер указателя на след элемент
  228.         {
  229.             m_next = next;
  230.         }
  231.     }; // подкласс "элемент стека" закончиося
  232.     void updateSize () // измерение размера стека
  233.     {
  234.         for (const Node* node = m_head ;node != nullptr; node = node->next())
  235.         {
  236.             ++m_size;
  237.         }
  238.     }
  239. private:
  240.     const Node* m_head = nullptr; //головной элемент
  241.     size_t m_size = 0; //размер стека, в начале 0
  242. public:
  243.     Stack<T> () {} //конструктор стека
  244.     Stack<T> (const Stack<T>& other) // конструктор копирования
  245.     {
  246.         *this = other; // this - это наш стек, с которым идет работа
  247.     }
  248.     void push (const T& element) //пуш - добавление 1 элемента
  249.     {
  250.         m_head = new Node(element, m_head); //передвинули голову
  251.         ++m_size; //увеличили размер
  252.     }
  253.     const T& top () const //показать головной элемент
  254.     {
  255.         return m_head->data();
  256.     }
  257.     void pop () //поп - убрать элемент
  258.     {
  259.         const Node* tmp = m_head; //решил вопрос через временный указатель
  260.         m_head = m_head->next();
  261.         delete tmp;
  262.         --m_size;// уменьшить размер
  263.     }
  264.     ~Stack() // деструктор
  265.     {
  266.         while (!empty())
  267.         {
  268.             pop();
  269.         }
  270.     }
  271.     bool empty() const // проверка на пустоту
  272.     {
  273.         return m_head == nullptr;
  274.     }
  275.     size_t size () const //вычисление размера
  276.     {
  277.         return m_size;
  278.     }
  279.     const Stack<T>& operator=(const Stack<T>& other) //оператор равно
  280.     {
  281.         m_head = recursiveCopy(other.m_head);
  282.         m_size = other.m_size;
  283.         return *this;
  284.     }
  285.     bool operator==(const Stack<T>& other)
  286.     {
  287.         return (this->size() == other.size()) && this->contains(other);
  288.     }
  289. protected:
  290.     const Node* recursiveCopy(const Node* node, const Condition<T>& condition = Condition<T>(), bool wanted = true) const // динамичекий полиморфизм - когда используем объект дочернего класса как объект базового класса
  291.     {
  292.         for (;(node != nullptr) && (condition(node->data()) != wanted); node = node->next()) {} // тут и юзаем оператор скобки!, когда не where - отрабатывает на всем
  293.         if (node == nullptr) return nullptr;
  294.         return new Node(node->data(), recursiveCopy(node->next(), condition, wanted));
  295.     }
  296. public:
  297.     friend ostream& operator<<(ostream& os, const Stack<T>& stack) //friend  может в приват - печаталка
  298.     {
  299.         for (const Node* node = stack.m_head; node != nullptr; node = node->next())
  300.         {
  301.             os << node->data() << (node->next() == nullptr ? "" : ",");
  302.         }
  303.         if (stack.empty()) os << "stack is empty";
  304.         return os;
  305.     }
  306.     Stack<T> where(const Condition<T>& condition) const //РАБОЧИЙ WHERE)) - вместо condition в мейне пилим один из трех where классов
  307.     {
  308.         Stack<T> result;
  309.         result.m_head = recursiveCopy(this->m_head, condition);
  310.         result.updateSize();
  311.         return result;
  312.     }
  313.     T reduce(const Operation<T>& operation) const // Рабочий REDUCE - вместо operation  ставится один из 3х редьюсов, в мейне
  314.     {
  315.         if (empty()) return T();
  316.         T res = m_head->data();
  317.         for (const Node* node = m_head->next(); node != nullptr; node = node->next())
  318.         {
  319.             res = operation (res, node->data());
  320.         }
  321.         return res;
  322.     }
  323.     size_t indexOf (const Stack<T>& sub) const
  324.     {
  325.         size_t index = 0;
  326.         for (const Node* indexNode = m_head; indexNode != nullptr; indexNode = indexNode->next(), ++index) //индекс Головы подстека.
  327.         {
  328.             bool enter = true;
  329.             for(const Node *node = indexNode, *subNode = sub.m_head; subNode != nullptr && node != nullptr; node = node->next(), subNode = subNode->next())
  330.             {
  331.                 enter = enter && (node->data() == subNode->data()) && !((node->next() == nullptr) && (subNode->next() != nullptr));
  332.             }
  333.             if (enter) return index;
  334.         }
  335.         return numeric_limits<size_t>::max(); // максимуим от size_t :: - вызов статического метода. а если индекс не найден - то вернет ЭТО вот "4294967295"
  336.     }
  337.     bool contains (const Stack<T>& sub) const // проверяет входит ли у нас элемент в стек или нет. Вспомогательная ф-я, для Вас, Андрей Владимирович
  338.     {
  339.         return indexOf(sub) != numeric_limits<size_t>::max();
  340.     }
  341.     pair<Stack<T>, Stack<T>> split (const Condition<T>& condition) const
  342.     {
  343.         pair<Stack<T>, Stack<T>> res;
  344.         res.first.m_head = recursiveCopy(this->m_head, condition);
  345.         res.second.m_head = recursiveCopy(this->m_head, condition, false);
  346.         res.first.updateSize();
  347.         res.second.updateSize();
  348.         return res;
  349.     }
  350. };
  351.  
  352. void testWhereInt1();
  353. void testWhereInt2();
  354. void testWhereInt3();
  355.  
  356. void testWhereFloat1();
  357. void testWhereFloat2();
  358. void testWhereFloat3();
  359.  
  360. void testWhereComplex1();
  361. void testWhereComplex2();
  362. void testWhereComplex3();
  363.  
  364. void testReduceInt1();
  365. void testReduceInt2();
  366.  
  367. void testReduceFloat1();
  368. void testReduceFloat2();
  369.  
  370. void testReduceComplex1();
  371. void testReduceComplex2();
  372.  
  373. void testIndexOfInt();
  374. void testIndexOfFloat();
  375. void testIndexOfComplex();
  376.  
  377. void testSplitInt();
  378. void testSplitFloat();
  379. void testSplitComplex();
  380.  
  381. void testAll();
  382. #endif //SAOKI_DIAMONDDOGS_H
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement