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