//SET2.CPP
//реализация АТД множество(набор символов)-класса Set
#include <iostream.h>
#include <stdlib.h>
#include <conio.h>
#include "set3spa.h"
template <class Stype> Set<Stype>::Set()
{SetPtr=new Stype[DEFSET];
if(!SetPtr)
 {cout<<"Ошибка распределения памяти.\n";
 exit(1);}
NumMember=0;
MaxSize=DEFSET;
}

template <class Stype> Set<Stype>::Set(int size)
{SetPtr=new Stype[size];
if(!SetPtr)
 {cout<<"Ошибка распределения памяти.\n";
 exit(1);}
NumMember=0;
MaxSize=size;
}

template <class Stype> Set<Stype>::Set(const Set<Stype> &ASet)
{int i;
MaxSize=ASet.MaxSize;
SetPtr=new Stype[MaxSize];
if(!SetPtr)
 {cout<<"Ошибка распределения памяти.\n";
 exit(1);}
NumMember=0;
for(i=0;i<ASet.NumMember;i++)
 insert(ASet.SetPtr[i]);}

template <class Stype> void Set<Stype>::insert(Stype member)
{if(NumMember==MaxSize)
 {cout<<"Множество заполнено.\n";exit(1);}
if(!ismember(member))
 {SetPtr[NumMember]=member;
 NumMember++;}
}
template <class Stype> void Set<Stype>::remove(Stype member)
{
int loc=find(member);
if (loc!=-1)
 {for(;loc<NumMember-1;loc++)
  SetPtr[loc]=SetPtr[loc+1];
  NumMember--;}
}

template <class Stype> int Set<Stype>::find(Stype member)
{for(int i=0;i<NumMember;i++)
 if(SetPtr[i]==member)return i;
 return -1;
}

template <class Stype> int Set<Stype>::ismember(Stype member)
{if(find(member)!=-1)return 1; else return 0;}

//Операция присваивания
//set=set1
template <class Stype>  Set<Stype> &Set<Stype>::operator=(Set<Stype> &ASet)
{if (SetPtr==ASet.SetPtr) return *this;
if (ASet.NumMember>MaxSize)
{delete SetPtr;
SetPtr=new Stype[ASet.NumMember];
if(!SetPtr)
 {cout<<"Ошибка распределения памяти.\n";
 exit(1);}
MaxSize=ASet.NumMember;}
NumMember=0;
for(int i=0;i<ASet.NumMember;i++)
 insert(ASet.SetPtr[i]);
return *this;}

//добавить в множество элемент
//set=set+item
template <class Stype>  Set<Stype> Set<Stype>::operator+(Stype member)
{int i;
Set<Stype> temp(NumMember+1);
for (i=0;i<NumMember;i++)
 temp.insert(SetPtr[i]);
temp.insert(member);
return temp;}

//добавить элемент в множество
//set=item+set
template <class Stype>  Set<Stype> operator+(Stype member,Set<Stype> &ASet)
{int i;
Set<Stype> temp(ASet.NumMember+1);
for (i=0;i<ASet.NumMember;i++)
 temp.insert(ASet.SetPtr[i]);
temp.insert(member);
return temp;}

// объединение множеств
// set=set1+set2
template <class Stype>  Set<Stype> Set<Stype>:: operator+(Set<Stype> &ASet)
{int i;
Set<Stype> temp(NumMember+ASet.NumMember);
for (i=0;i<NumMember;i++)
 temp.insert(SetPtr[i]);
for (i=0;i<ASet.NumMember;i++)
 temp.insert(ASet.SetPtr[i]);
return temp;}

//Операция удаления из множества элемента
//set=set-item
template <class Stype>  Set<Stype> Set<Stype>::operator-(Stype member)
{Set<Stype> temp=*this;
temp.remove(member);
return temp;
}

//разность множеств
//set=set1-set2
template <class Stype>  Set<Stype> Set<Stype>::operator-(Set<Stype> &ASet)
{int i;
Set<Stype> temp=*this;
for(i=0;i<NumMember;i++)
 {if (ASet.ismember(SetPtr[i]))
   temp.remove(SetPtr[i]); }
return temp;
}

//пересечение множеств
//set=st1*set2
template <class Stype>  Set<Stype> Set<Stype>::operator*(Set<Stype> &ASet)
{int i;
Set<Stype> temp(NumMember);
for(i=0;i<NumMember;i++)
 if(ASet.ismember(SetPtr[i])) temp.insert(SetPtr[i]);
return temp;}

//проверка на равенство
template <class Stype>  int Set<Stype>::operator==(Set<Stype> &ASet)
{
if(NumMember!=ASet.NumMember) return 0;
return *this<ASet;
}

//проверка на неравенство
template <class Stype>  int Set<Stype>::operator!=(Set<Stype> &ASet)
{ return !(*this==ASet); }

//проверка на подмножество
template <class Stype>  int Set<Stype>::operator<(Set<Stype> &ASet)
{ for(int i=0;i<NumMember;i++)
   if(!ASet.ismember(SetPtr[i]))return 0;
return 1; }

//проверка принадлежности элемента множеству
template <class Stype>  int operator<(Stype member,Set<Stype> &ASet)
{return ASet.ismember(member);}

//конструирование множества
template<class Stype> Set<Stype> &Set<Stype>::operator()(int k,...)
{int d=(sizeof(char)+1)/2*2;
char *pc=(char*)(&k+1);
if(k>MaxSize)
{delete[] SetPtr;
SetPtr=new Stype[k];
if(!SetPtr)
 {cout<<"Ошибка распределения памяти.\n";
 exit(1);}
MaxSize=k;}
NumMember=0;
for(;k;k--,pc=pc+d)
insert(*(pc));
return *this;
}

//Оператор вывода
//cout<<set
template <class Stype>  ostream &operator<<(ostream &stream,Set<Stype> &ASet)
{
for(int i=0;i<ASet.NumMember;i++)
 stream<<ASet.SetPtr[i]<<" ";
 stream<<endl;
 return stream;}

//Оператор ввода
//cin>>set
template <class Stype>  istream &operator>>(istream &stream,Set<Stype> &ASet)
{Stype member;
ASet.NumMember=0;
do
{stream>>member;
ASet=ASet+member;}
while(stream.peek()!='\n');
return stream;
}





