426 lines
8.4 KiB
C++
426 lines
8.4 KiB
C++
#include <stdio.h>
|
|
|
|
#include "sage++user.h"
|
|
#include "definesValues.h"
|
|
#include "set.h"
|
|
|
|
#ifdef __SPF
|
|
extern "C" void addToCollection(const int line, const char *file, void *pointer, int type);
|
|
extern "C" void removeFromCollection(void *pointer);
|
|
#endif
|
|
|
|
Set::Set(int(*feq)(void *e1, void *e2),
|
|
void *(*fcomb)(void *e1, void *e2),
|
|
void(*fp)(void *e1))
|
|
{
|
|
|
|
data = NULL;
|
|
nbelement = 0;
|
|
nballocated = 0;
|
|
equal = feq;
|
|
combine = fcomb;
|
|
printEl = fp;
|
|
deallocelem = 0;
|
|
}
|
|
|
|
void Set::printSet()
|
|
{
|
|
int i;
|
|
if (!printEl)
|
|
{
|
|
Message("Function printEl not given", 0);
|
|
return;
|
|
}
|
|
if (!this->size())
|
|
printf("Empty set\n");
|
|
else
|
|
{
|
|
for (i = 0; i < this->size(); i++)
|
|
{
|
|
(*printEl)(getElement(i));
|
|
}
|
|
printf("\n");
|
|
}
|
|
}
|
|
|
|
void Set::interSet(Set *s1, Set *s2)
|
|
{
|
|
int i, j;
|
|
int trouve;
|
|
void *e1, *e2;
|
|
if (!equal)
|
|
return;
|
|
if (!s1 || !s2)
|
|
return;
|
|
if (!equal)
|
|
{
|
|
Message("Function Equal not given", 0);
|
|
return;
|
|
}
|
|
for (i = 0; i < s1->size(); i++)
|
|
{
|
|
e1 = s1->getElement(i);
|
|
if (e1)
|
|
{
|
|
trouve = 0;
|
|
for (j = 0; j < s2->size(); j++)
|
|
{
|
|
e2 = s2->getElement(j);
|
|
if ((*equal)(e1, e2))
|
|
{
|
|
trouve = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (trouve)
|
|
this->addElement(e1);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Set::unionSet(Set *s1)
|
|
{
|
|
int i, j;
|
|
int trouve;
|
|
void *e1, *e2;
|
|
int initsize;
|
|
int initsize2;
|
|
|
|
if (!s1)
|
|
{
|
|
return;
|
|
}
|
|
if (!equal)
|
|
{
|
|
Message("Function Equal not given", 0);
|
|
return;
|
|
}
|
|
initsize = s1->size();
|
|
initsize2 = this->size();
|
|
for (i = 0; i < initsize; i++)
|
|
{
|
|
e1 = s1->getElement(i);
|
|
if (e1)
|
|
{
|
|
trouve = 0;
|
|
for (j = 0; j < initsize2; j++)
|
|
{
|
|
e2 = this->getElement(j);
|
|
if ((*equal)(e1, e2))
|
|
{
|
|
trouve = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (!trouve)
|
|
this->addElement(e1);
|
|
}
|
|
}
|
|
}
|
|
int Set::equalSet(Set *s1)
|
|
{
|
|
int i, j;
|
|
int trouve;
|
|
void *e1, *e2;
|
|
if (!s1)
|
|
return 0;
|
|
|
|
if (!equal)
|
|
{
|
|
Message("Function Equal not given", 0);
|
|
return 0;
|
|
}
|
|
if (this->size() != s1->size())
|
|
return 0;
|
|
|
|
for (i = 0; i < size(); i++)
|
|
{
|
|
e1 = getElement(i);
|
|
if (e1)
|
|
{
|
|
trouve = 0;
|
|
for (j = 0; j < s1->size(); j++)
|
|
{
|
|
e2 = s1->getElement(j);
|
|
if ((*equal)(e1, e2))
|
|
{
|
|
trouve = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (!trouve)
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int Set::isInSet(void *e1)
|
|
{
|
|
int i, j;
|
|
int trouve;
|
|
void *e2;
|
|
if (!e1)
|
|
return 0;
|
|
if (!equal)
|
|
{
|
|
Message("Function Equal not given", 0);
|
|
return 0;
|
|
}
|
|
for (i = 0; i < size(); i++)
|
|
{
|
|
e2 = getElement(i);
|
|
if (e1)
|
|
{
|
|
if ((*equal)(e1, e2))
|
|
{
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void Set::diffSet(Set *s1, Set *s2)
|
|
{
|
|
int i, j;
|
|
int trouve;
|
|
void *e1, *e2;
|
|
int initsize;
|
|
if (!s2)
|
|
{
|
|
if (s1)
|
|
{
|
|
for (i = 1; i < s1->size(); i++)
|
|
{
|
|
e1 = s1->getElement(i);
|
|
this->addElement(e1);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
if (!equal)
|
|
{
|
|
Message("Function Equal not given", 0);
|
|
return;
|
|
}
|
|
initsize = s1->size();
|
|
for (i = 0; i < initsize; i++)
|
|
{
|
|
e1 = s1->getElement(i);
|
|
if (e1)
|
|
{
|
|
trouve = 0;
|
|
for (j = 1; j < s2->size(); j++)
|
|
{
|
|
e2 = s2->getElement(j);
|
|
if ((*equal)(e1, e2))
|
|
{
|
|
trouve = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (!trouve)
|
|
this->addElement(e1);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
void Set::Reallocatedata()
|
|
{
|
|
int i;
|
|
void **pt;
|
|
|
|
pt = new void *[nballocated + ALLOCATECHUNKSET];
|
|
|
|
#ifdef __SPF
|
|
addToCollection(__LINE__, __FILE__, pt, 2);
|
|
#endif
|
|
for (i = 0; i < nballocated + ALLOCATECHUNKSET; i++)
|
|
pt[i] = NULL;
|
|
|
|
for (i = 0; i < nballocated; i++)
|
|
pt[i] = data[i];
|
|
|
|
if (nballocated)
|
|
{
|
|
#ifdef __SPF
|
|
removeFromCollection(data);
|
|
#endif
|
|
delete[] data;
|
|
}
|
|
data = pt;
|
|
nballocated = nballocated + ALLOCATECHUNKSET;
|
|
}
|
|
|
|
void Set::addElement(void *el)
|
|
{
|
|
if (!el)
|
|
return;
|
|
// should check if already here
|
|
if (nbelement >= MAXELEMENT)
|
|
{
|
|
Message("Too many element in set", 0);
|
|
return;
|
|
}
|
|
while (nballocated <= (nbelement + 1))
|
|
{
|
|
Reallocatedata();
|
|
}
|
|
data[nbelement] = el;
|
|
nbelement++;
|
|
}
|
|
|
|
|
|
|
|
Set *Set::compact()
|
|
{
|
|
int i, k;
|
|
int trouve;
|
|
Set *newset;
|
|
if (!equal)
|
|
{
|
|
Message("Function Equal not given", 0);
|
|
return NULL;
|
|
}
|
|
// look at duplicate elements, and combine (to see later) if necessary
|
|
newset = new Set(equal, combine, printEl);
|
|
#ifdef __SPF
|
|
addToCollection(__LINE__, __FILE__, newset, 1);
|
|
#endif
|
|
for (i = 0; i < this->size(); i++)
|
|
{
|
|
trouve = 0;
|
|
for (k = 0; k < newset->size(); k++)
|
|
{
|
|
if ((*equal)(data[i], newset->data[k]))
|
|
{
|
|
trouve = 1;
|
|
break;
|
|
}
|
|
}
|
|
if (!trouve && data[i])
|
|
{
|
|
newset->addElement(data[i]);
|
|
}
|
|
}
|
|
return newset;
|
|
}
|
|
|
|
|
|
|
|
Set *Set::combineSet()
|
|
{
|
|
int i, j, inisize;
|
|
int change;
|
|
Set *newset, *temp;
|
|
void *pt;
|
|
int step = 0;
|
|
if (!combine)
|
|
{
|
|
Message("Function Combine not given", 0);
|
|
return NULL;
|
|
}
|
|
temp = this->copy();
|
|
change = 1;
|
|
|
|
while (change)
|
|
{
|
|
step++;
|
|
change = 0;
|
|
inisize = temp->size();
|
|
for (i = 0; i < inisize; i++)
|
|
{
|
|
for (j = i + 1; j < inisize; j++)
|
|
{
|
|
if (temp->getElement(i) && temp->getElement(j))
|
|
{
|
|
pt = combine(temp->getElement(i), temp->getElement(j));
|
|
if (pt)
|
|
{
|
|
temp->addElement(pt);
|
|
change = 1;
|
|
temp->rmElement(j);
|
|
temp->rmElement(i);
|
|
}
|
|
else
|
|
temp->addElement(pt);
|
|
}
|
|
}
|
|
}
|
|
if (step > MAXITDATAFLOW)
|
|
{
|
|
Message("Combine set is Looping", 0);
|
|
break;
|
|
}
|
|
}
|
|
///////////////////////////////
|
|
// PAS DE DESALLOCATION //
|
|
///////////////////////////////
|
|
// newset = temp;
|
|
// temp = temp->compact();
|
|
// if (newset)
|
|
// delete newset;
|
|
return temp;
|
|
}
|
|
|
|
Set *Set::copy()
|
|
{
|
|
int i, k;
|
|
Set *newset;
|
|
newset = new Set(equal, combine, printEl);
|
|
#ifdef __SPF
|
|
addToCollection(__LINE__, __FILE__, newset, 1);
|
|
#endif
|
|
for (i = 0; i < this->size(); i++)
|
|
{
|
|
if (data[i])
|
|
newset->addElement(data[i]);
|
|
}
|
|
return newset;
|
|
}
|
|
|
|
void *Set::getElement(int i) const
|
|
{
|
|
void *pt;
|
|
if ((i < 0) || (i >= nbelement))
|
|
return NULL;
|
|
pt = data[i];
|
|
return pt;
|
|
}
|
|
|
|
void *Set::rmElement(int i)
|
|
{
|
|
void *pt;
|
|
if ((i < 0) || (i >= nbelement))
|
|
return NULL;
|
|
pt = data[i];
|
|
data[i] = NULL;
|
|
return pt;
|
|
}
|
|
|
|
Set::~Set()
|
|
{
|
|
int i;
|
|
if (data)
|
|
{
|
|
if (deallocelem)
|
|
{
|
|
for (i = 0; i < nbelement; i++)
|
|
{
|
|
#ifdef __SPF
|
|
removeFromCollection(data[i]);
|
|
#endif
|
|
delete [](char*)data[i];
|
|
}
|
|
}
|
|
#ifdef __SPF
|
|
removeFromCollection(data);
|
|
#endif
|
|
delete []data;
|
|
}
|
|
}
|