Last active
November 4, 2017 19:29
-
-
Save thejavalistener/d42513be2350b9c177ad489565676350 to your computer and use it in GitHub Desktop.
TAD Index (en realidad, ya es práctsicamente una clase).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
#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