Advertisement
Guest User

/r/arkadye set

a guest
Jan 6th, 2015
188
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.81 KB | None | 0 0
  1. // myset.h
  2.  
  3. #include <vector> // Internal representation.
  4. #include <algorithm> // Sorting, comparing.
  5. #include <initializer_list>
  6. #include <string>
  7. #include <sstream>
  8. #include <iostream>
  9.  
  10. //typedef int T;
  11. template <typename T>
  12. class Set
  13. {
  14. private:
  15.     std::vector<T> data;
  16.     bool compl;
  17.  
  18.     // Utility functions
  19.     static void cleanUpData(std::vector<T>& dat)
  20.     {
  21.         std::sort(dat.begin(), dat.end());
  22.         dat.erase(std::unique(dat.begin(), dat.end()), dat.end());
  23.     }
  24.  
  25.     static std::vector<T> mergeData(const std::vector<T> left, const std::vector<T> right)
  26.     {
  27.         auto result = std::vector<T>{};
  28.         std::merge(left.begin(), left.end(), right.begin(), right.end(), std::back_inserter(result));
  29.         cleanUpData(result);
  30.         return result;
  31.     }
  32.  
  33.     static std::vector<T> unionData(const std::vector<T> left, const std::vector<T> right)
  34.     {
  35.         auto result = std::vector<T>{};
  36.         std::copy_if(left.begin(), left.end(), std::back_inserter(result),
  37.             [&right](const T& item) {return std::binary_search(right.begin(), right.end(), item); });
  38.         return result;
  39.     }
  40.  
  41.     static std::vector<T> eraseData(const std::vector<T>& original, const std::vector<T>& toBeRemoved)
  42.     {
  43.         auto result = std::vector<T>{};
  44.         std::copy_if(original.begin(), original.end(), std::back_inserter(result),
  45.             [&toBeRemoved](const T& item){return !std::binary_search(toBeRemoved.begin(), toBeRemoved.end(), item); });
  46.         return result;
  47.     }
  48.  
  49.     // Build the vectors: used this way so we can make const Sets.
  50.     std::vector<T> makeVector(const std::initializer_list<T>& init) const
  51.     {
  52.         auto dat = std::vector<T>{ init };
  53.         cleanUpData(dat);
  54.         return dat;
  55.     }
  56.  
  57.     template <typename Iterator>
  58.     std::vector<T> makeVector(const Iterator& start, const Iterator& finish) const
  59.     {
  60.         auto dat = std::vector<T>{ start, finish };
  61.         cleanUpData(dat);
  62.         return dat;
  63.     }
  64.  
  65.     // One true constructor
  66.     Set(std::vector<T>&& dat, bool complement) : data(dat), compl(complement) {}
  67. public:
  68.     template <typename Type> friend Set<Type> operator&&(const Set<Type>&, const Set<Type>&); // Intersection operator.
  69.     template <typename Type> friend Set<Type> operator||(const Set<Type>&, const Set<Type>&); // Union operator
  70.     template <typename Type> friend std::ostream& operator<<(std::ostream&, const Set<Type>&);
  71.  
  72.     // Make this STL compatible.
  73.     typedef typename std::vector<T>::const_iterator const_iterator;
  74.     typedef typename std::vector<T>::const_reverse_iterator const_reverse_iterator;
  75.     const_iterator cbegin() const { return data.cbegin(); }
  76.     const_iterator cend() const { return data.cend(); }
  77.     const_reverse_iterator crbegin() const { return data.crbegin(); }
  78.     const_reverse_iterator crend() const { return data.crend(); }
  79.     const_iterator begin() const { return cbegin(); }
  80.     const_iterator end() const { return cend(); }
  81.     const_reverse_iterator rbegin() const { return crbegin(); }
  82.     const_reverse_iterator rend() const { return crend(); }
  83.  
  84.     // CONSTRUCTORS
  85.     Set() : Set(vector<T>{},false) {}
  86.     Set(const Set&) = default;
  87.     template <typename T2> Set(const Set<T2>& rhs) : Set(rhs.begin(), rhs.end()) {}
  88.     Set(Set&& rvs) : Set(std::move(rvs.data), rvs.compl) {}
  89.     Set(const std::initializer_list<T>& il) : Set(makeVector(il),false) {}
  90.     template <typename It> Set(const It& start, const It& finish) : Set(makeVector(start, finish), false) {}
  91.  
  92.     Set operator=(const Set& rhs) { data = rhs.data; compl = rhs.compl; return *this; }
  93.     Set operator=(Set&& rhs) { data = std::move(rhs.data); compl = rhs.compl; return *this; }
  94.  
  95.     // Set operations
  96.     Set complement() const
  97.     {
  98.         return Set(std::vector<T>(data), !compl);
  99.     }
  100.  
  101.     bool contains(const T& val) const
  102.     {
  103.         return std::binary_search(data.begin(), data.end(), val) == compl;
  104.     }
  105. };
  106.  
  107. template <typename T>
  108. std::string to_string(const Set<T>& input)
  109. {
  110.     std::ostringstream oss;
  111.     oss << input;
  112.     return oss.str();
  113. }
  114.  
  115. template <typename Type>
  116. std::ostream& operator<<(std::ostream& os, const Set<Type>& set)
  117. {
  118.     if (set.compl) os << '!';
  119.     if (set.data.empty())
  120.     {
  121.         os << "{}";
  122.         return os;
  123.     }
  124.     os << '{' << *(set.begin());
  125.     for (auto it = set.begin() + 1; it != set.end(); ++it)
  126.     {
  127.         os << ", " << *it;
  128.     }
  129.     os << '}';
  130.     return os;
  131. }
  132.  
  133. // EQUALS FUNCTION
  134. // Normal overload. Both sets are the same size.
  135. template<typename T>
  136. bool operator==(const Set<T>& left, const Set<T>& right)
  137. {
  138.     if (left.size() != right.size())
  139.     {
  140.         return false;
  141.     }
  142.     const auto result = std::mismatch(begin(left), end(left), begin(right));
  143.     return result.first == end(left);
  144. }
  145.  
  146. // UNION OPERATOR
  147. template<typename T>
  148. Set<T> operator||(const Set<T>& left, const Set<T>& right)
  149. {
  150.     if (!left.compl && !right.compl)
  151.     {
  152.         return Set<T>(Set<T>::mergeData(left.data, right.data), false);
  153.     }
  154.     else if (!left.compl && right.compl)
  155.     {
  156.         return Set<T>(Set<T>::eraseData(right.data, left.data),true);
  157.     }
  158.     else if (left.compl && !right.compl)
  159.     {
  160.         return right || left;
  161.     }
  162.     else if (left.compl && right.compl)
  163.     {
  164.         return Set<T>(Set<T>::unionData(left.data, right.data), true);
  165.     }
  166.     return Set<T>{};
  167. }
  168.  
  169. template <typename T1, typename T2>
  170. Set<T1> operator||(const Set<T1>& left, const Set<T2>& right)
  171. {
  172.     return left || Set<T1>(right);
  173. }
  174.  
  175. // INTERSECTION OPERATOR
  176. template<typename T>
  177. Set<T> operator&&(const Set<T>& left, const Set<T>& right)
  178. {
  179.     if (!left.compl && !right.compl)
  180.     {
  181.         return Set<T>(Set<T>::unionData(left.data, right.data), false);
  182.     }
  183.     else if (!left.compl && right.compl)
  184.     {
  185.         return Set<T>(Set<T>::eraseData(left.data, right.data), true);
  186.     }
  187.     else if (left.compl && !right.compl)
  188.     {
  189.         return right && left;
  190.     }
  191.     else if (left.compl && right.compl)
  192.     {
  193.         return Set<T>(Set<T>::mergeData(left.data, right.data), true);
  194.     }
  195.     return Set<T>{};
  196. }
  197.  
  198. template <typename T1, typename T2>
  199. Set<T1> operator&&(const Set<T1>& left, const Set<T2>& right)
  200. {
  201.     return left && Set<T1>(right);
  202. }
  203.  
  204. // Complement operator
  205. template <typename T>
  206. Set<T> operator!(const Set<T> in)
  207. {
  208.     return in.complement();
  209. }
  210.  
  211. // main.cpp
  212.  
  213. #include "myset.h"
  214.  
  215. #include <iostream>
  216.  
  217. using namespace std;
  218.  
  219. template <typename T>
  220. void printSet(string name, const Set<T>& set)
  221. {
  222.     cout << name << " = " << set << '\n';
  223. }
  224.  
  225. int main()
  226. {
  227.     auto setI = Set<int>{1, 2, 7, 9};
  228.     auto setS = Set<short>{3, 6};
  229.     auto setI2 = Set<int> {2, 6, 439};
  230.     auto setI3 = Set<int>(begin(setI), end(setI));
  231.  
  232.     printSet("SetI", setI);
  233.     printSet("SetS", setS);
  234.     printSet("SetI2", setI2);
  235.     printSet("SetI3", setI3);
  236.  
  237.     printSet("SetI && SetI2", setI && setI2);
  238.     printSet("!SetI && SetI2", !setI && setI2);
  239.     printSet("SetI && !SetI2", setI && !setI2);
  240.     printSet("!SetI && !SetI2", !setI && !setI2);
  241.    
  242.     printSet("SetI || SetI2", setI || setI2);
  243.     printSet("!SetI || SetI2", !setI || setI2);
  244.     printSet("SetI || !SetI2", setI || !setI2);
  245.     printSet("!SetI || !SetI2", !setI || !setI2);
  246.  
  247.     setI3 = setI2;
  248.     printSet("setI3 =  setI2", setI3);
  249.  
  250.     printSet("int SetI", Set<int>(setS));
  251.  
  252.     cin.get();
  253. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement