Departamento de Lenguajes y Ciencias de la Computacion
LABORATORIO DE PROGRAMACION
Examen Ordinario de Junio

Realizar un programa cuyo objetivo sera la generacion de un indice para un documento de texto.

El indice estara compuesto por una tabla hash de 32 claves con encadenamiento, cuya funcion hash vendra determinada por el valor ASCII de la primera letra de la palabra en modulo 32.

El encadenamiento de palabras dentro de una misma clave sera implementado utilizando una lista enlazada simple ordenada (por la palabra misma).

Para cada palabra se debera almacenar tanto su cadena de caracteres como la lista de posiciones que ocupa dentro del fichero (ya que una misma palabra puede aparecer multiples veces en un mismo documento). La lista de posiciones se mantendra como una lista enlazada simple ordenada de enteros.

Este programa debera constar al menos de los siguientes modulos (LA DEFINICION DE LOS MODULOS NO SE PODRA MODIFICAR):

MError
Tipo enumerado TError con los posibles valores:
- Ok : Operacion sin error.
- EstructuraLlena : La operacion no pudo efectuarse por falta de espacio en la estructura. 
- ElementoInexistente : La operacion no pudo efectuarse por no encontrarse el elemento.
- ElementoExistente : La operacion no pudo efectuarse porque la estructura ya contiene dicho elemento.

- MListaEnteros
Tipo TListaEnteros
TListaEnteros CreaListaEnteros ();
/* Funcion que crea una lista de enteros */
void DestruyeListaEnteros (TListaEnteros &l);
/* Funcion que destruye una lista de enteros */
void InsertaListaEnteros (TListaEnteros &l, int valor, TError &error);
/* Inserta en orden el nuevo valor. Si el elemento ya se encuentra en la lista no se modifica la misma y se devuelve el error ElementoExistente */
bool ListaEnterosVacia (TListaEnteros l);
/* Funcion que indica si la lista esta vacia */
bool ListaEnterosLlena (TListaEnteros l);
/* Funcion que indica si la lista esta llena */
void SacaPrimeroListaEnteros (TListaEnteros &l, int &valor, TError &error);
/* Extrae el primer elemento de la lista, devolviendo su valor y eliminandolo de la misma. Devolvera el error ElementoInexistente si la lista se encuentra vacia */

- MPalabra
Tipo TPalabra
Tipo enumerado TComparacion con los posibles valores:
- igual : Las dos palabras son iguales.
- mayor : La primera palabra es mayor en orden alfabetico que la segunda. 
- menor : La primera palabra es menor en orden alfabetico que la segunda.
TComparacion ComparaPalabras (TPalabra p1, TPalabra p2);
/* Compara dos palabras indicando si p1 es menor, igual o mayor que p2. La comparacion de palabras sera sensible a mayusculas y minusculas, y se realizara atendiendo exclusivamente a la cadena de caracteres que la consituye, sin tener en cuenta la lista de posiciones en el fichero */
TPalabra CreaPalabra (string palabra);
/* Crea una palabra partiendo de la cadena indicada */
void DestruyePalabra (TPalabra &p);
/* Destruye la palabra indicada */
void NuevaPosicion (TPalabra &p, int posicion, TError &error);
/* Aade la posicion indicada en la lista de posiciones */
void Palabra (TPalabra p, string &c);
/* Devuelve la cadena de caracteres de la palabra especificada */
void SacaPrimeraPosicion (TPalabra &p, int &posicion, TError &error);
/* Devuelve la primera posicion en la lista, eliminandola de la lista */

- MListaPalabras
Tipo TListaPalabras
TListaPalabras CreaListaPalabras ();
/* Funcion que crea una lista de palabras */
void DestruyeListaPalabras (TListaPalabras &l);
/* Funcion que destruye una lista de palabras */
void InsertaListaPalabras (TListaPalabras &l, TPalabra valor, TError &error);
/* Inserta en orden el nuevo valor de palabra. Si ya se encuentra en la lista no se modifica la misma y se devuelve el error ElementoExistente */
bool ListaPalabrasVacia (TListaPalabras l);
/* Funcion que indica si la lista esta vacia */
bool ListaPalabrasLlena (TListaPalabras l);
/* Funcion que indica si la lista esta llena */
void SacaPrimeroListaPalabras (TListaPalabras &l, TPalabra &valor, TError &error);
/* Extrae el primer elemento de la lista, devolviendo su valor y eliminandolo de la misma. Devolvera el error ElementoInexistente si la lista se encuentra vacia */

- MIndice
Tipo TIndice
void CreaIndice (TIndice &i);
/* Crea un indice vacio */
void DestruyeIndice (TIndice &i);
/* Destruye el indice, dejandolo nuevamente vacio */
void NuevaAparicion (TIndice &i, string palabra, int posicion, TError &error);
/* Aade una nueva aparicion en el indice para una palabra determinada. Si la palabra ya existia incluye la nueva posicion en su lista de posiciones. nicamente devuelve un error si falta memoria para realizar la operacion (EstructuraLlena) o bien si se intenta insertar una palabra y posicion que ya existia (ElementoExistente) */
void LeeIndiceFichero (ifstream &fi, TIndice &i, TError &error);
/* Destruye el indice actual y lo vuelve a generar a partir del contenido del fichero binario especificado en el descriptor */
void EscribeIndiceFichero (ofstream &of, TIndice &i);
/* Almacena el indice actual en el fichero binario especificado en el descriptor. El indice en memoria debera preservarse tras la llamada */
void EscribeIndicePantalla (TIndice &i);
/* Escribe el indice actual en la pantalla, debiendose preservar el valor del indice en memoria tras la llamada */

La interfaz del programa se realizara mediante un menu que se detalla seguidamente:

INDICE
------
A. Construir indice para fichero de texto
B. Mostrar indice
C. Almacenar indice en fichero binario
D. Leer indice de fichero binario
X. Salir

De las opciones del menu anterior, las OPCIONES BASICAS que deben realizar TODOS LOS ALUMNOS son:

- Opcion A: Solicitara el nombre de un fichero de texto, destruira el indice actualmente en memoria y generara uno nuevo para el archivo de texto especificado. En el fichero de texto de entrada se reconoceran aquellas palabras compuestas exclusivamente por letras, cualquier otro caracter se considerara como separador.

- Opcion X: Destruira el indice y finalizara la ejecucion del programa.

Los ALUMNOS QUE NO TENGAN SUPERADO EL TRABAJO EN CLASE (tienen una nota acumulada < 2), ademas tendran que implementar las siguientes opciones del menu principal:

- Opcion B: Mostrara el indice construido para el archivo.

El formato de salida del indice por pantalla sera:
	palabra: palabra
	posicion: posicion1 posicion2 posicion3 ...
Por ejemplo:
	palabra: pepe
	posicion: 10 45 1245
	palabra: juan
	posicion: 90
	palabra: bueno
	posicion: 120 256 423 1045

Una vez completadas las operaciones pedidas, PARA SACAR MAS NOTA se podran implementar las siguientes opciones adicionales:

- Opcion C: Almacenara el indice en un fichero binario, cuyo nombre debera solicitarse al usuario. El formato de los ficheros binarios para almacenar los indices es libre, la unica restriccion es que el programa debe ser capaz de leer los ficheros que almacena.

- Opcion D: Destruira el indice actualmente en memoria y generara uno nuevo partiendo de la informacion almacenada en el fichero binario cuyo nombre se solicitara al usuario.

NOTAS IMPORTANTES:

- Debido a un fallo del compilador de C++ integrado en Dev-C++, el metodo tellg (), que permite obtener la posicion del cursor en un flujo de entrada, no funciona correctamente en ficheros de texto. Por ello, el fichero de texto de entrada debera o bien manejarse en formato binario, o bien leyendo el fichero caracter a caracter usando una funcion del tipo: void LeePalabra (ifstream &fich, string &palabra, int &posIni, int &posFin)
- Observese tambien que, a excepcion del tipo TIndice, no existen funciones para recorrer e imprimir las listas, por lo que para realizar las operaciones de imprimir o escribir en fichero binario listas sera necesario extraer e insertar los elementos de las mismas, pudiendo utilizarse las estructuras adicionales para almacenamiento temporal que se crean oportunas, pero de tal forma que al final del proceso las listas queden con el mismo contenido inicial.

CONSIDERACIONES SOBRE EL EXAMEN:

- Es obligatorio trabajar en una carpeta con nombre LPGES10.
- El proyecto Dev-C++ debera denominarse "jun10_indice.dev"
- Todo PROGRAMA QUE NO COMPILE o tenga efectos laterales se considerara SUSPENSO.
- Se podran aadir tipos auxiliares en las cabeceras de los modulos para completar los tipos indicados.
- Queda completamente prohibido aadir ninguna funcion o procedimiento publico en los ficheros de cabecera de los modulos indicados, asi como alterar las cabeceras de las funciones especificadas.
- Se podran aadir cuantas funciones, procedimientos y tipos privados a los modulos que se considere oportunos.
- Se podran aadir cuantos modulos adicionales se estime oportuno, siempre y cuando no esten destinados a sustituir alguno de los modulos anteriormente indicados.
- El uso de detalles de implementacion de un modulo, fuera del modulo de implementacion del mismo sera CAUSA de SUSPENSO, es decir, en el programa principal o en modulos distintos a los mencionados anteriormente no se podra hacer cosas tipo: l= NULL, ptr=ptr->sig, etc.
- Se recomienda y valora el tratamiento de errores y la buena descomposicion del programa principal en procedimientos y funciones, asi como el uso de procedimientos y funciones auxiliares dentro de la implementacion de los modulos cuando estas sean necesarias.
