Advertisement
avr39ripe

listOperatorPlus_operatorMult_clone

Aug 7th, 2020
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.30 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. template <typename ElemT>
  4. class List
  5. {
  6.     class Node
  7.     {
  8.     public:
  9.         ElemT data;
  10.         Node* next;
  11.         Node* prev;
  12.         Node(const ElemT& dataP, Node* nextP = nullptr, Node* prevP = nullptr)
  13.             :data{ dataP }, next{ nextP }, prev{ prevP } {};
  14.     };
  15.  
  16.     Node* head;
  17.     Node* tail;
  18.     size_t size;
  19.     Node* getNode(size_t idx);
  20. public:
  21.     List() : head{ nullptr }, tail{ nullptr }, size{ 0 } {}
  22.     List(const List& listP) : head{ nullptr }, tail{ nullptr }, size{ 0 }
  23.     {
  24.         for (List::Node* curr{ listP.head }; curr; curr = curr->next)
  25.         {
  26.             push_back(curr->data);
  27.         }
  28.         std::cout << "Copy-shmopy!\n";
  29.     };
  30.     List(List&& listP) : head{ listP.head }, tail{ listP.tail }, size{ listP.size }
  31.     {
  32.         listP.head = nullptr;
  33.         listP.tail = nullptr;
  34.         listP.size = 0;
  35.         std::cout << "I liket to mov'it, mov'it! :[]\n";
  36.     };
  37.     List(const std::initializer_list<ElemT> initList) : head{ nullptr }, tail{ nullptr }, size{ 0 }
  38.     {
  39.         for (const auto& elem : initList)
  40.         {
  41.             push_back(elem);
  42.         }
  43.     };
  44.     ElemT& front() { return head->data; };
  45.     const ElemT& front()const { return head->data; };
  46.     ElemT& back() { return tail->data; };
  47.     const ElemT& back()const { return tail->data; };
  48.     const size_t getSize() const { return size; };
  49.     bool empty() const { return size == 0; };
  50.     void push_back(const ElemT& data);
  51.     void push_front(const ElemT& data);
  52.     bool pop_back();
  53.     bool pop_front();
  54.     void clear();
  55.     ElemT& operator[](size_t idx);
  56.     void insertAt(size_t idx, const ElemT& data);
  57.     void deleteAt(size_t idx);
  58.     ~List();
  59.     template <typename ElemT>
  60.     friend std::ostream& operator<<(std::ostream& out, const List<ElemT>& list)
  61.     {
  62.         out << "[ ";
  63.         for (List<ElemT>::Node* curr{ list.head }; curr; curr = curr->next)
  64.         {
  65.             out << curr->data << ' ';
  66.         }
  67.         out << "]";
  68.         return out;
  69.     };
  70.  
  71.     template <typename ElemT>
  72.     friend List<ElemT> operator+(const List<ElemT>& lhs, const List<ElemT>& rhs)
  73.     {
  74.         List<ElemT> res;
  75.         for (List::Node* curr{ lhs.head }; curr; curr = curr->next)
  76.         {
  77.             res.push_back(curr->data);
  78.         }
  79.         for (List::Node* curr{ rhs.head }; curr; curr = curr->next)
  80.         {
  81.             res.push_back(curr->data);
  82.         }
  83.         return res;
  84.     };
  85.  
  86.     template <typename ElemT>
  87.     friend List<ElemT> operator*(const List<ElemT>& lhs, const List<ElemT>& rhs)
  88.     {
  89.         List<ElemT> res;
  90.         for (List::Node* currL{ lhs.head }; currL; currL = currL->next)
  91.         {
  92.             for (List::Node* currR{ rhs.head }; currR; currR = currR->next)
  93.             {
  94.                 if (currL->data == currR->data)
  95.                 {
  96.                     res.push_back(currL->data);
  97.                     break;
  98.                 }
  99.             }
  100.         }
  101.  
  102.         for (List::Node* currR{ rhs.head }; currR; currR = currR->next)
  103.         {
  104.             for (List::Node* currL{ lhs.head }; currL; currL = currL->next)
  105.             {
  106.                 if (currL->data == currR->data)
  107.                 {
  108.                     res.push_back(currL->data);
  109.                     break;
  110.                 }
  111.             }
  112.         }
  113.         return res;
  114.     };
  115. };
  116.  
  117. template <typename ElemT>
  118. void List<ElemT>::push_back(const ElemT& data)
  119. {
  120.     Node* tmp{ tail };
  121.     tail = new Node{ data, nullptr, tail };
  122.     if (tmp)
  123.     {
  124.         tmp->next = tail;
  125.     }
  126.     ++size;
  127.  
  128.     if (!head)
  129.     {
  130.         head = tail;
  131.     }
  132.     //if (!head)
  133.     //{
  134.     //  head = new Node{ data };
  135.     //  tail = head;
  136.     //}
  137.     //else
  138.     //{
  139.     //  tail->next = new Node{ data, nullptr, tail };
  140.     //  tail = tail->next;
  141.     //}
  142.     //++size;
  143. }
  144.  
  145. template <typename ElemT>
  146. void List<ElemT>::push_front(const ElemT& data)
  147. {
  148.     Node* tmp{ head };
  149.     head = new Node{ data, head, nullptr };
  150.     if (tmp)
  151.     {
  152.         tmp->prev = head;
  153.     }
  154.     ++size;
  155.  
  156.     if (!tail)
  157.     {
  158.         tail = head;
  159.     }
  160. }
  161.  
  162. template <typename ElemT>
  163. bool List<ElemT>::pop_front()
  164. {
  165.     if (head)
  166.     {
  167.         if (tail == head)
  168.         {
  169.             delete tail;
  170.             size = 0;
  171.             tail = nullptr;
  172.             head = nullptr;
  173.             return true;
  174.         }
  175.  
  176.         Node* tmp{ head };
  177.         head = head->next;
  178.         head->prev = nullptr;
  179.         delete tmp;
  180.         --size;
  181.         return true;
  182.     }
  183.     return false;
  184. }
  185. template <typename ElemT>
  186. bool List<ElemT>::pop_back()
  187. {
  188.     if (tail)
  189.     {
  190.         if (tail == head)
  191.         {
  192.             delete tail;
  193.             size = 0;
  194.             tail = nullptr;
  195.             head = nullptr;
  196.             return true;
  197.         }
  198.  
  199.         Node* tmp{ tail };
  200.         tail = tail->prev;
  201.         tail->next = nullptr;
  202.         delete tmp;
  203.         --size;
  204.         return true;
  205.     }
  206.     return false;
  207. }
  208.  
  209. template <typename ElemT>
  210. void List<ElemT>::clear()
  211. {
  212.     while (tail)
  213.     {
  214.         std::cout << "Clear for: " << back() << '\n';
  215.         pop_back();
  216.     }
  217. }
  218.  
  219. template <typename ElemT>
  220. List<ElemT>::~List()
  221. {
  222.     while (head)
  223.     {
  224.         pop_front();
  225.     }
  226. }
  227.  
  228. template<typename ElemT>
  229. typename List<ElemT>::Node* List<ElemT>::getNode(size_t idx)
  230. {
  231.     Node* curr{ nullptr };
  232.     int cnt;
  233.  
  234.     if (idx >= 0 and idx < size)
  235.     {
  236.         if (idx > (size / 2))
  237.         {
  238.             for (curr = tail, cnt = size - 1; cnt > idx; curr = curr->prev, --cnt);
  239.         }
  240.         else
  241.         {
  242.             for (curr = head, cnt = 0; cnt < idx; curr = curr->next, ++cnt);
  243.         }
  244.     }
  245.     return curr;
  246. }
  247.  
  248. template <typename ElemT>
  249. ElemT& List<ElemT>::operator [](size_t idx)
  250. {
  251.     return getNode(idx)->data;
  252. };
  253.  
  254. template<typename ElemT>
  255. void List<ElemT>::insertAt(size_t idx, const ElemT& data)
  256. {
  257.     Node* curr = getNode(idx);
  258.     if (!curr or curr == tail) { push_back(data); return; };
  259.  
  260.     Node* newNode = new Node{ data, curr->next, curr };
  261.     curr->next = newNode;
  262.     newNode->next->prev = newNode;
  263.     ++size;
  264. }
  265.  
  266. template<typename ElemT>
  267. void List<ElemT>::deleteAt(size_t idx)
  268. {
  269.     Node* curr = getNode(idx);
  270.     if (curr)
  271.     {
  272.         if (curr->prev) { curr->prev->next = curr->next; }
  273.         else { head = curr->next; }
  274.         if (curr->next) { curr->next->prev = curr->prev; }
  275.         else { tail = curr->prev; }
  276.  
  277.         --size;
  278.  
  279.         if (curr == head and curr == tail)
  280.         {
  281.             head = nullptr;
  282.             tail = nullptr;
  283.             size = 0;
  284.         }
  285.  
  286.         delete curr;
  287.     }
  288.  
  289. }
  290.  
  291. int main()
  292. {
  293.     List<int> a;
  294.     a.push_back(1);
  295.     a.push_back(2);
  296.     a.push_back(3);
  297.     a.push_back(4);
  298.     std::cout << "a -> " << a << '\n';
  299.  
  300.     List<int> b{a};
  301.     std::cout << "b -> " << b << '\n';
  302.  
  303.     List<int> c;
  304.     c.push_back(5);
  305.     c.push_back(6);
  306.     c.push_back(7);
  307.     c.push_back(8);
  308.     std::cout << "c -> " << c << '\n';
  309.  
  310.     List<int> d{ b + c };
  311.     std::cout << "d -> " << d << '\n';
  312.  
  313.     List<int> e{ 1,3,5,7,3,5,7,1 };
  314.     List<int> f{ 2,1,4,6,7,1,6,7 };
  315.     std::cout << "e -> " << e << '\n';
  316.     std::cout << "f -> " << f << '\n';
  317.  
  318.     List<int> g{ e * f };
  319.     std::cout << "g -> " << g << '\n';
  320.  
  321.     return 0;
  322. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement