Skip to content

Instantly share code, notes, and snippets.

@thejavalistener
Last active November 4, 2017 19:29
Show Gist options
  • Save thejavalistener/d42513be2350b9c177ad489565676350 to your computer and use it in GitHub Desktop.
Save thejavalistener/d42513be2350b9c177ad489565676350 to your computer and use it in GitHub Desktop.
TAD Index (en realidad, ya es práctsicamente una clase).
#ifndef _TIDX_TAD_
#define _TIDX_TAD_
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include "../template/files.hpp"
#include "../template/lists.hpp"
#include "List.hpp"
using namespace std;
template<typename K>
struct IndexInfo
{
long pos;
K info;
};
template<typename K, typename T>
struct Index
{
private: FILE* f;
private: List<IndexInfo<K> > i;
// funciones callback
private: int (*cmpKK)(K,K);
private: K (*tToK)(T);
private: int cmpIndexInfo(IndexInfo<K> i1, IndexInfo<K> i2)
{
return this->cmpKK(i1.info,i2.info);
}
private: void _sort(List<IndexInfo<K> >& lst,K cmpKK(K,K))
{
bool ordenado=false;
while(!ordenado)
{
Node<IndexInfo<K> >* aux = lst.p;
ordenado=true;
while(aux->sig!=NULL)
{
K* k1 = &(aux->info.info);
K* k2 = &(aux->sig->info.info);
if( cmpKK(*k1,*k2)>0 )
{
ordenado=false;
IndexInfo<K>* ii1 = &(aux->info);
IndexInfo<K>* ii2 = &(aux->sig->info);
IndexInfo<K> tmp = aux->info;
*ii1=*ii2;
*ii2=tmp;
cout << "k1="<<*k1;
cout << ", k2="<<*k2;
cout << endl;;
}
aux=aux->sig;
}
}
}
private: Node<IndexInfo<K> >* _find(Node<IndexInfo<K> >* p,K k,int cmpKK(K,K))
{
Node<IndexInfo<K> >* aux = p;
while( aux!=NULL )
{
if(cmpKK(aux->info.info,k)==0)
{
return aux;
}
aux = aux->sig;
}
return NULL;
}
public: Index(FILE* f, int (*cmpKK)(K,K),K (*tToK)(T))
{
this->f = f;
this->i = listCreate<IndexInfo<K> >();
this->cmpKK=cmpKK;
this->tToK=tToK;
long posInic = ftell(f);
seek<T>(f,0);
T t = read<T>(f);
while( !feof(f) )
{
IndexInfo<K> ii;
ii.pos = filePos<T>(f)-1;
ii.info = tToK(t);
listAdd<IndexInfo<K> >(this->i,ii);
t = read<T>(f);
}
_sort(i,cmpKK);
listReset<IndexInfo<K> >(i);
fseek(f,posInic,SEEK_SET);
}
public: bool contains(K k)
{
return _find(i.p,k,cmpKK)!=NULL;
}
public: bool contains(K k, int cmpKK(K,K))
{
return _find(i.p,k,cmpKK)!=NULL;
}
public: T get(K k)
{
return get(k,cmpKK);
}
public: T get(K k, int cmpKK(K,K))
{
Node<IndexInfo<K> >* aux = _find(i.p,k,cmpKK);
long pos = aux->info.pos;
seek<T>(f,pos);
T t = read<T>(f);
i.curr = aux->sig;
return t;
}
public: T next()
{
// busco la posicion
IndexInfo<K>* x = listNext<IndexInfo<K> >(i);
long pos=x->pos;
// leo en el archivo
seek<T>(f,pos);
return read<T>(f);
}
public: bool hasNext()
{
return listHasNext<IndexInfo<K> >(i);
}
public: void reset()
{
listReset<IndexInfo<K> >(i.i);
}
public: void free()
{
listFree<IndexInfo<K> >(i);
}
};
#endif
//
#include <iostream>
#include "tad/Index.hpp" // funciones de listas y estrucutas dinamicas
#include "template/files.hpp" // funciones de archivos
#include <string.h>
using namespace std;
int cmpInt(int a,int b)
{
return a-b;
}
struct Persona
{
int idPersona;
int dni;
char nombre[25];
int fechaNac;
};
int personaToDNI(Persona p)
{
return p.dni;
}
int main()
{
// abro el archivo
FILE* f = fopen("ARCHIVO.dat","r+b");
// creo un indice
Index<int,Persona>* idx = new Index<int,Persona>(f,cmpInt,personaToDNI);
// mientras haya siguiente
while( idx->hasNext() )
{
// pido el proximo registro
Persona p = idx->next();
// muestro
cout << p.dni<<", "<<p.nombre<<endl;
}
cout << "---" << endl;
// si existe una persona con DNI=3552
if( idx->contains(3552) )
{
// leo ese registro
Persona x = idx->get(3552);
// lo muestro
cout << x.nombre<< endl;
}
// libero el indice (la lista)
idx->free();
fclose(f);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment