utiles_v2017/garray_ord.h

156 lines
3.7 KiB
C++
Raw Blame History

#include "garray.h"
//array generico ordenado---------------------------------
#ifndef CARRAY_ORD_DEF
#define CARRAY_ORD_DEF
#define GARRAY_O_MODO_EXACTO 0 //devuelve el elemento exacto si esta en la lista si no null
#define GARRAY_O_MODO_MENOR 1//devuelve el elemento menor mas cercano de la lista(si existe)
#define GARRAY_O_MODO_MAYOR 2//devuelve el elemento mayor mas cercano de la lista (si existe)
template<typename T1, typename T2>
class Cgarray_ord
{
public:
Cgarray<int> ind;
Cgarray<T1> dat;
public:
int (*f_ord)(T1* e1,T1*e2);//resultado de comparar e1 con e2
int (*fcomp)( T2 * t, T1*e);//resultado de comparar t con e
int modo;
//**************************************************************
Cgarray_ord(){f_ord=NULL; fcomp=NULL;modo=GARRAY_O_MODO_EXACTO;};
~Cgarray_ord(){};
//**************************************************************
inline T1& operator[](int i)//da el elemento i-esimo por referencia
{
return dat[ind[i]];
};
//**************************************************************
inline int getix(T2*index)//da el indice elemento segun indexado
{
int f=dat.n-1, i=0 ,a=-1,res;
if((fcomp==NULL))
return -1;
if(dat.n<=0)
return -1;
//dicotomica-------------------
while(f-i>1)
{
a=(f-i)/2+i;
res=fcomp(index,get(a));
if (res<0)
f=a;
else if (res>0)
i=a;
else
return a;
}
res=fcomp( index,get(f));
if(res==0)
return f;
else if (res<0 && modo==GARRAY_O_MODO_MAYOR)
return f;
res=fcomp( index, get(i));
if(res==0)
return i;
else if(res>0 && modo==GARRAY_O_MODO_MENOR)
return i;
else if (res<0 && modo==GARRAY_O_MODO_MAYOR)
return f;
return -1;
};
//**************************************************************
inline T1* getx(T2*index)//da el elemento segun indexado
{
int i=getix(index);
if(i<0)
return NULL;
return dat.get(ind[i]) ;
};
//**************************************************************
inline T1* get(int i)//da el elemento i-esimo
{
return dat.get(ind[i]) ;
};
//**************************************************************
inline BOOL operator+(T1 &e )//a<>ade nuevo elemento
{
int f=dat.n-1, i=0 ,a=-1,res;
if((f_ord==NULL) || !(ind+=1) || !(dat+e) )
return FALSE;
//dicotomica-------------------
while(f-i>1)
{
a=(f-i)/2+i;
res=f_ord(&e,get(a));
if (res<0)
f=a;
else if (res>0)
i=a;
else
f=i=a;
}
if (f<0)
{
a=0;
}
else if (i!=f || a<0)
{
res=f_ord(&e,get(f));
if (res>0)
a=f+1;
else if (0>f_ord(&e,get(i)))
{
a=i;
}
else
a=f;
}
if ((a)<ind.n)
memcpy(&ind.ptr[a+1],&ind.ptr[a], sizeof(int)*(ind.n-a));
ind.n++;
ind[a]=dat.n-1;
return TRUE ;
};
//**************************************************************
inline BOOL operator+=(int mas )//a<>ade memoria para mas elementos
{
return ((dat+=mas) && (ind+=mas));
};
//**************************************************************
inline BOOL operator-=(int i )//borra el elemento iesimo
{
int idi=ind[i];
for(idi=0; idi<ind.n; idi++)
{
if(ind[idi]>ind[0])
ind[idi]--;
}
if(i<(ind.n-1))
memcpy(ind.get(i), ind.get(i+1), sizeof(int)*(ind.n-i-1));
if((idi+1)<dat.n)
memcpy(dat.get(idi),dat.get(idi+1), sizeof(T1)*(dat.n-idi-1));
dat.n--;
ind.n--;
return TRUE;
};
//**************************************************************
inline BOOL operator-(T2*index )//borra el elemento correspondiente a el index
{
int idi= getix(index);
return (idi>=0)&& operator-=(idi);
};
//**************************************************************
inline void borra()//libera la memoria del array
{
ind.borra();
dat.borra();
}
//**************************************************************
};
#endif