Advertisement
JustRp

Class Set

May 29th, 2011
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 21.54 KB | None | 0 0
  1. #include <iostream>
  2. #include <conio.h>
  3. #include <assert.h>
  4.  
  5. using namespace std;
  6.  
  7. /*
  8.  *  Реализация класса множеств, перегрузка операторов.
  9.  *
  10.  *  *****
  11.  *  29.05.2011
  12. **/
  13.  
  14. //Формат комментариев функций: [возвращаемая информация] [входящая информация] [задача функции]
  15.  
  16. struct element            
  17. {
  18.     int v;          
  19.     struct element * next;
  20. };
  21.  
  22.  
  23.  
  24.  
  25. //Класс "множество"
  26. class set
  27. {          
  28.     public:
  29.         set():power(0),rear(NULL){};
  30.         set(const set & s);
  31.         set(int p);
  32.         set(int * a, int sz);
  33.         ~set();
  34.         friend ostream & operator <<(ostream & out, const set & s);
  35.         set & operator --(); //prefix
  36.         set & operator --(int); //postfix
  37.         operator int() { return power; }
  38.         short operator == (const set & s) const;
  39.         set & operator = (const set & s);
  40.         friend set operator +(int el, const set & s);  
  41.         set operator +(const int el) const;                                      
  42.         set operator +(const set & s)const;              
  43.         set operator -(const int el) const;
  44.         set operator -(const set & s2) const;            
  45.         set operator & (const set & s2)const;
  46.         set operator ^ (const set & s)const;
  47.         short operator < (const set & s) const;          
  48.         short operator > (const set & s) const { return (s < *this);}                      
  49.         short operator < (int el) const;        
  50.         set & operator += (const int el);  
  51.         set & operator += (const set & s);                                                                
  52.         set & operator -= (const set & s);                                  
  53.         set & operator -= (const int el);                                  
  54.         set & operator &= (const set & s);
  55.         set & operator ^= (const set & s);                                                                          
  56.              
  57.     private:
  58.         int power;        
  59.         struct element * rear;
  60.         void push(int val);
  61.         struct element * contains(int v) const;
  62.         void delEl(struct element * p);
  63. };
  64.  
  65. void set::push(int val)                                                        
  66. {
  67.     struct element * newEl = new element;
  68.     newEl->v = val;
  69.     power++;
  70.     if (rear)                       //если список не пустой
  71.     {
  72.         newEl->next = rear->next;
  73.         rear->next = newEl;
  74.         rear = newEl;            
  75.     }
  76.     else                            //если список пустой, закольцовываем его
  77.     {
  78.         newEl->next = newEl;
  79.         rear = newEl;
  80.     }
  81. }
  82.  
  83. set set::operator ^(const set &s) const                                                                 //TEST
  84. {
  85.     if (power==0)           //если одно из множеств пустое, симм. разность будет равна другому мн-ву
  86.         return s;
  87.     if (s.power == 0)
  88.         return *this;
  89.     set newS;
  90.     if (*this == s)        //если множества равны, симм.разность равна пустому мн-ву.      
  91.         return newS;
  92.     newS = (*this);
  93.     newS = newS + (*this);
  94.     newS^=s;
  95.     return newS;
  96. }
  97.  
  98. set::set(int * a, int sz):power(0),rear(NULL)           //конструктор, изымающий множество из массива                    
  99. {
  100.     push(a[0]);
  101.     for (int i=1; i<sz; i++)
  102.     {
  103.         if (!contains(a[i]))
  104.             push(a[i]);
  105.     }  
  106. }
  107.  
  108. struct element * set::contains(int val) const //ищет элемент в множестве и возвращает указатель на него                            
  109. {
  110.     if (!rear)
  111.         return 0;
  112.     struct element * p = rear;
  113.     do
  114.     {
  115.         if (p->v == val)
  116.             return p;
  117.         p = p->next;
  118.     } while (p != rear);
  119.     return NULL;
  120. }
  121.  
  122. void set::delEl(struct element * p)
  123. {
  124.     power--;
  125.     delete p;
  126. }
  127.  
  128. set::set(const set & s):power(0),rear(NULL)     //копирующий конструктор
  129. {
  130.     if (s.rear)
  131.     {
  132.         struct element * p = s.rear->next;
  133.         do            
  134.         {                           //почленное копирование      
  135.             push(p->v);
  136.             p = p->next;
  137.         } while (p != s.rear->next);
  138.     }
  139. }
  140.  
  141. set::~set()
  142. {
  143.     if (power)                              //если содержит элементы, значит есть что удалять
  144.     {
  145.         struct element * p;
  146.         do                               //удаляем последовательно все элементы
  147.         {                                  
  148.             p = rear->next;
  149.             rear->next = p->next;
  150.             delEl(p);
  151.         } while (power);
  152.     }
  153. }
  154.  
  155. ostream & operator <<(ostream & out, const set & s)
  156. {
  157.     if (s.power == 0)           //пусто
  158.     {
  159.         out<<"Empty set"<<endl;
  160.         return out;
  161.     }
  162.     int i;                      //не пусто
  163.     struct element * p = s.rear->next;
  164.     out<<"power["<<s.power<<"]"<<endl;
  165.     do
  166.     {
  167.         out<<p->v<<"   ";          //последовательный вывод значений эл-в мн-ва через пробел
  168.         p = p->next;
  169.     } while (p != s.rear->next);
  170.     out<<endl;
  171.     return out;
  172. }
  173.  
  174. set & set::operator --()                //удаление первого элемента
  175. {                    
  176.     struct element * p = rear->next;
  177.     rear->next = p->next;
  178.     delEl(p);
  179.     return (*this);
  180. }
  181.  
  182. set & set::operator --(int)             //удаление последнего элемента
  183. {
  184.     *this -= rear->v;
  185.     return (*this);
  186. }
  187.  
  188. short set::operator == (const set & s) const
  189. {
  190.     if (power != s.power)                   //если мощности множеств не равны, множества не равны
  191.         return 0;
  192.     if (power == 0)                         //два пустых множества равны
  193.         return 1;
  194.     struct element * p = s.rear;
  195.     do                                      //пробег по всем элементам одного множества              
  196.     {
  197.         if (!contains(p->v))                //если во втором множестве не содержится такого элемента,
  198.             return 0;                       //то множества не равны
  199.         p = p->next;
  200.     } while (p != s.rear);
  201.     return 1;                               //иначе - равны.
  202. }
  203.  
  204. set & set::operator = (const set & s)                       //присваивание
  205. {
  206.     if (s == *this)
  207.         return *this;
  208.     if (s.power == 0)
  209.     {
  210.         delete this;
  211.         power=0;
  212.         return *this;
  213.     }
  214.     int i = 0, min=(power<s.power?power:s.power);           //i - счетчик, max - минимальная мощность двух множеств.
  215.     struct element *p = (power?rear->next:NULL), *p2 = s.rear->next;                 //р2 - указатель на эл-т присваивоемого мн-ва, р  - указатель на элемент другого мн-ва.
  216.     for (i = 0; i < min; i++)      //копируем все, что влазит
  217.     {      
  218.         p->v = p2->v;
  219.         p = p->next;
  220.         p2 = p2->next;
  221.        
  222.     }
  223.     if (power < s.power)                    //если не влазит, добавляем
  224.     {
  225.         for (;i < s.power; i++)
  226.         {
  227.             push(p2->v);
  228.             p2 = p2->next;
  229.         }
  230.     }
  231.     else                                    //если остается лишнее место, удаляем
  232.     {
  233.         while (power != s.power)
  234.             (*this)--;
  235.     }
  236.     power=s.power;
  237.     return *this;
  238. }
  239.  
  240. set operator +(int el, const set & s)                       //элемент+множество
  241. {
  242.     set newS(s);                    //копируем множество
  243.     if (!newS.contains(el))
  244.     {
  245.         newS.push(el);                  //добавляем в конец
  246.         struct element *p = newS.rear;  //и притворяемся, что это - начало.
  247.         while(p->next != newS.rear)
  248.             p = p->next;
  249.         newS.rear = p;
  250.     }
  251.     return newS;
  252. }
  253.  
  254. set set::operator +(const int el)const  
  255. {
  256.     set newS = *this;
  257.     if (!newS.contains(el))            
  258.         newS.push(el);
  259.     return newS;
  260. }
  261.  
  262. set set::operator +(const set & s)const         //сложение(объединение)множеств
  263. {
  264.     if (*this == s || s.power == 0)
  265.         return *this;                              
  266.     if (power == 0)
  267.         return s;
  268.     set newS;
  269.     struct element *p2 = s.rear->next;        //р2 - указатель на правое множество ((левое_множество+правое_множество))
  270.     int i = 0;
  271.     if (power >= s.power)            //маленькая оптимизация
  272.     {
  273.         newS = *this;                   //копируем большее множество
  274.         do                              //и добавляем в него элементы меньшего
  275.         {                                                              
  276.             newS+=p2->v;
  277.             p2 = p2->next;
  278.         } while (p2 != s.rear->next);
  279.     }
  280.     else
  281.     {
  282.         return (s+(*this));
  283.     }
  284.     return newS;
  285. }
  286.  
  287.  
  288. set set::operator -(const int el) const
  289. {
  290.     set newS;                       //создаем пустое множество
  291.     struct element *p = rear->next;
  292.     do                            //и копируем внего все элементы множества-уменьшаемого
  293.     {                               //за исключением эквивалентного элементу
  294.         if (p->v != el)
  295.             newS.push(p->v);
  296.         p = p->next;
  297.     } while (p != rear->next);
  298.     return newS;
  299. }
  300.  
  301. set set::operator -(const set & s2) const                //разность множеств                      
  302. {
  303.     if (s2.power == 0)              //если вычитаемое пусто, разность равна вычитаемому
  304.         return *this;
  305.     set newS;
  306.     if (((power == s2.power) && (*this == s2)) || power == 0) //если мн-ва равны (или уменьшаемое пусто), возвращаем пустое множество
  307.     {
  308.         return newS;
  309.     }
  310.     struct element *p = rear->next;              
  311.     int i;      
  312.     do              //Для всех элементов уменьшаемого множества:
  313.     {
  314.        
  315.         if (!s2.contains(p->v))      //если эл-т не содержится в вычитаемом множестве, добавляем его в разность.
  316.             newS.push(p->v);  
  317.         p = p->next;
  318.     } while (p != rear->next);                
  319.     return newS;
  320. }
  321.  
  322. set set::operator & (const set & s2)const               //пересечение множеств
  323. {
  324.    
  325.     if ((power == s2.power)&&(*this == s2))             //если множества равны, возращаем любое из них
  326.         return *this;
  327.     set spike; set spike2; set newS;
  328.     if ((power == 0) || (s2.power == 0))                //если одно из множеств пусто, возвращаем пустое множество
  329.         return newS;
  330.     struct element *p = rear->next;
  331.    
  332.     if (power <= s2.power)                     //небольшая оптимизация
  333.     {
  334.         do      
  335.         {
  336.             if (s2.contains(p->v))       //если элемент одного множества содержится в другом, добавляем его в результирующее мн-во
  337.                 newS.push(p->v);
  338.             p = p->next;
  339.         } while( p != rear->next);
  340.     }
  341.     else
  342.     {
  343.         newS = s2 & *this;
  344.     }
  345.     return newS;
  346. }
  347.  
  348. set & set::operator += (const int el)                                        
  349. {
  350.     if (power == 0 || !contains(el))   //добавляем эл-т в мн-во
  351.         push(el);
  352.     return *this;
  353. }  
  354.  
  355. set & set::operator +=(const set & s) //добавление множества в множество
  356. {
  357.     if (*this > s) //если добавляемое множество является подмножеством, делаем ничего.
  358.         return *this;
  359.     struct element *p = s.rear->next;
  360.     do  //добавляем все элементы множества
  361.     {
  362.         *this += p->v;
  363.         p = p->next;
  364.     } while (p != s.rear->next);
  365.     return *this;
  366. }
  367.  
  368. set & set::operator -=(const int el) //изъятие эл-та из мн-ва          
  369. {
  370.     struct element *p = contains(el);
  371.     if (p==NULL || power == 0)
  372.         return *this;         //из пустого множества не получится изъять. Так же не изъять то, чего нет.
  373.     if ((power == 1) & (p != NULL))        //если единственный элемент
  374.     {
  375.         delEl(rear);
  376.         rear = NULL;
  377.         return *this;
  378.     }
  379.     if (p == rear)                     //если конечный элемент
  380.     {
  381.         do
  382.         {
  383.             p = p->next;                //приходится заморачиваться с изменением указателя на хвост
  384.         } while (p->next != rear);
  385.         p->next = rear->next;
  386.         delEl(rear);
  387.         rear = p;
  388.     }
  389.     else
  390.     {
  391.         struct element *tmp = p->next;
  392.         p->v = p->next->v;
  393.         p->next = p->next->next;        //просто вынимаем элемент из списка
  394.         if (tmp == rear)
  395.             rear = p;
  396.         delEl(tmp);
  397.        
  398.     }
  399.     return *this;
  400. }
  401.  
  402. set & set::operator -=(const set & s) //вычесть множество из множества      
  403. {
  404.     if (s.power == 0)              //из пустого множества не вычесть
  405.         return *this;
  406.     struct element *p = s.rear->next;
  407.     do   //вычесть каждый член вычитаемого множества из уменьшаемого множества
  408.     {
  409.         *this-=p->v;
  410.         p = p->next;
  411.     } while (p != s.rear->next);
  412.     return *this;
  413. }
  414.  
  415. set & set::operator &= (const set & s)       //пересечение с изменением
  416. {
  417.      if (s.power == 0 || power == 0 || (power == s.power && *this == s)) //если изменений нет, возвратить без изменений
  418.         return *this;
  419.      if (*this < s)         //если является подмножеством, изменений нет
  420.         return *this;
  421.     int i = 0;
  422.     struct element *p = rear->next,*res,*tmp,*del;  //res - результирующий список элементов
  423.     res = NULL;                                     //tmp - для swap'a;
  424.     del = NULL;                                     //del - удаляемые элементы
  425.     do                              //проверяем все элементы изменяемого множества по очереди
  426.     {  
  427.         if (s.contains(p->v))       //если элемент содержится во втором множестве
  428.         {                           //то он идет в результирующий список
  429.             tmp = res;
  430.             res = p;
  431.             p = p->next;
  432.             res->next = tmp;
  433.             i++;
  434.         }
  435.         else
  436.         {
  437.             tmp = del;          //иначе - удаляется
  438.             del = p;
  439.             p = p->next;
  440.             del->next = tmp;
  441.         }
  442.         power--;
  443.     } while (power && p);
  444.     p = del;
  445.     while (p && p->next)         //удаляем все неводшедшие в пересечение элементы
  446.     {
  447.         tmp = p->next;
  448.         delEl(p);
  449.         p = tmp;
  450.     }
  451.     delEl(p);
  452.     p = res;
  453.     power = i;
  454.     if (p)
  455.     {
  456.         while (p->next)     //находим конец результирующего списка - и замыкаем его.
  457.             p = p->next;
  458.         p->next = res;
  459.     }
  460.     rear = p;           //и обновляем данные в результирующем множестве.
  461.     return *this;
  462. }
  463.  
  464. set & set::operator ^= (const set & s)
  465. {
  466.     if (s.power == 0 || power == 0) //если изменений нет, возвращаем сразу
  467.         return *this;
  468.     if (*this == s)                     //если множества равны, удаляем все элементы
  469.     {
  470.         struct element *p;        
  471.         do{
  472.             p = rear->next;
  473.             delEl(rear);
  474.             rear = p;
  475.         } while (power);  
  476.         rear = NULL;
  477.         return *this;
  478.     }
  479.     struct element *p = s.rear;
  480.     do   //каждый элемент, содержащийя в обоих множествах удаляется
  481.     {                                   //каждый элемент, содержащийся только в правом множестве добавляется в левое
  482.         if (contains(p->v))
  483.             (*this)-=(p->v);                
  484.         else
  485.             (*this)+=(p->v);        
  486.         p = p->next;
  487.     } while (p != s.rear);
  488.     return *this;
  489. }
  490.  
  491.  
  492. short set::operator < (const set & s) const
  493. {
  494.     if (power>s.power)              //если мощность правого множества больше мощности левого, оно не может быть подмножеством.
  495.         return 0;
  496.     if (power == 0)                 //пустое множество - подмножество любого множества
  497.         return 1;
  498.     struct element * p = rear->next;
  499.     do
  500.     {
  501.         if (!s.contains(p->v))      //если хотя бы один элемент левого мн-ва не принадлежит к правому мн-у, левое мн-во не
  502.             return 0;               //является подмножеством правого
  503.         p = p->next;
  504.     } while (p != rear->next);
  505.     return 1;                       //иначе - является.
  506. }
  507.  
  508. short set::operator < (int el) const    //принадлежность элемента множеству
  509. {
  510.     if (contains(el))  
  511.         return 1;
  512.     else
  513.         return 0;
  514. }
  515.  
  516. void doSomething()
  517. {
  518.     int ar[]={1,2,3,4},br[]={1,5,6,7,8,9},cr[]={1,4,9};
  519.         set a(ar,4);
  520.         set b(br,6);
  521.         set c(cr,3);
  522.     /*
  523.         cout<<"Enter 4 elements for set a"<<endl;
  524.         set a(4);
  525.         cout<<"Enter 6 elements for set b"<<endl;
  526.         set b(6);
  527.         cout<<"Enter 3 elements for set c"<<endl;
  528.         set c(3);
  529. */
  530.     cout<<"Set d will be empty"<<endl;
  531.     set d;
  532.     cout<<"Lets make new set j = a"<<endl;
  533.     set j;
  534.     j = a;
  535.    
  536.     cout<<"---------------------------------------------"<<endl;
  537.     cout<<"Set a:"<<a<<"Set b:"<<b<<"Set c:"<<c<<"Set d:"<<d<<"Set j:"<<j;    
  538.     cout<<"a+b=";
  539.     cout<<"="<<(a+b);
  540.     cout<<"a+a="<<(a+a);
  541.     cout<<"d+c="<<(d+c);
  542.    
  543.     cout<<"---------------------------------------------"<<endl;
  544.    
  545.  
  546.    
  547.     cout<<"Set a:"<<a<<"Set b:"<<b<<"Set c:"<<c<<"Set d:"<<d;
  548.    
  549.     cout<<"b-c="<<(b-c);
  550.     cout<<"d-a="<<(d-a);
  551.     cout<<"c-d="<<(c-d);
  552.    
  553.     cout<<"---------------------------------------------"<<endl;
  554.     cout<<"Set a:"<<a<<"Set b:"<<b<<"Set c:"<<c<<"Set d:"<<d;
  555.     cout<<"Enter x. Then we will do b-x, x+a and c+x"<<endl;
  556.     int x;
  557.     cin>>x;
  558.     cout<<"b-"<<x<<"="<<(b-x);
  559.     cout<<x<<"+a"<<"="<<(x+a);
  560.     cout<<"c+"<<x<<"="<<(c+x);
  561.    
  562.     if (b==b)
  563.         cout<<"b==b"<<endl;
  564.     else
  565.         cout<<"b!=b"<<endl;
  566.    
  567.     if (d==a)
  568.         cout<<"d==a"<<endl;
  569.     else
  570.         cout<<"d!=a"<<endl;
  571.    
  572.     cout<<"---------------------------------------------"<<endl;
  573.     cout<<"Set a:"<<a<<"Set b:"<<b<<"Set c:"<<c<<"Set d:"<<d;
  574.     cout<<"Now let's do c-- and --c"<<endl;
  575.     cout<<"c-- = "<<(c--);
  576.     cout<<"--c = "<<(--c);
  577.     if (b<x)
  578.         cout<<"b<x"<<endl;
  579.     else
  580.         cout<<"b!<x"<<endl;
  581.     if (c<x)
  582.         cout<<"c<x"<<endl;
  583.     else
  584.         cout<<"c!<x"<<endl;
  585.     if (d<a)
  586.         cout<<"d<a"<<endl;
  587.     else
  588.         cout<<"d!<a"<<endl;
  589.     if (b>c)
  590.         cout<<"b>c"<<endl;
  591.     else
  592.         cout<<"b!>c"<<endl;
  593.  
  594.     cout<<"---------------------------------------------"<<endl;
  595.     cout<<"Set a:"<<a<<"Set b:"<<b<<"Set c:"<<c<<"Set d:"<<d;
  596.     cout<<"Now lets make set e=a&b"<<endl;
  597.     set e = a&b;
  598.     cout<<"Set e:"<<e;
  599.     cout<<"e^a="<<(e^a);
  600.    
  601.     cout<<"---------------------------------------------"<<endl;
  602.     cout<<"Set a:"<<a<<"Set b:"<<b<<"Set c:"<<c<<"Set d:"<<d<<"Set e:"<<e;
  603.     cout<<"Enter new x. We will c+=x; b-=x."<<endl;
  604.     cin>>x;
  605.     cout<<"c+=x = "<<(c+=x);
  606.     cout<<"b-=x = "<<(b-=x);
  607.     cout<<"c+=a = "<<(c+=a);
  608.     cout<<"b-=e = "<<(b-=e);
  609.     cout<<"a^=b = "<<(a^=b);            
  610.     cout<<"c&=e = "<<(c&=e);
  611.     cout<<"b&=(a-9) = "<<(b&=(a-9));
  612.    
  613.     cout<<"---------------------------------------------"<<endl;
  614.     cout<<"Set a:"<<a<<"Set b:"<<b<<"Set c:"<<c<<"Set d:"<<d<<"Set e:"<<e;
  615.     cout<<"a^=a = "<<(a^=a);
  616.     cout<<"That's all."<<endl;  
  617.     getch();
  618. }
  619.  
  620. int main()
  621. {
  622.     //doSomething();
  623.      set a,b;
  624.     a+=1;
  625.     a+=2;
  626.     b+=3;
  627.     b+=2;
  628.  
  629.  
  630.    
  631.     cout<<"+"<< (a + b) <<endl;
  632.     //cout<<"+="<< (a+=b) <<endl;
  633.     cout<<"-"<< (a - b) <<endl;
  634.     cout<<"a:"<<a<<"b:"<<b;
  635.     cout<<"^"<< (a ^ b) <<endl;
  636.     cout<<"&"<< (a & b) <<endl;
  637.     cout<<"end.";
  638.     cout<<"^="<<(b^=a)<<endl;
  639.     getch();
  640. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement