Document

Anuncio
Programación 2
Diseño recursivo de algoritmos
que trabajan con ficheros
Problemas
1
En los problemas que siguen se va a trabajar con
ficheros binarios de datos de tipo T :
<fichero_binario_T> ::= { <dato> }
<dato> ::= T
Asumiremos definidas las siguientes operaciones
binarias de relación entre un par de datos, a y b, de
tipo T :
a == b
a != b a < b
a <= b
a > b
a >= b
2
Problema 1. Diseñar sin bucles:
/*
* Pre: [nombre1] y [nombre2] son los nombres de dos ficheros
* binarios que almacenan secuencias de datos de tipo T
* Post: Devuelve cierto si y sólo si ambos ficheros almacenan
* el mismo número de datos
*/ template <typename T>
bool igualLongitud (const char nombre1[], const char nombre2[]);
3
/*
* Pre: [nombre1] y [nombre2] son los nombres de dos ficheros
* binarios que almacenan secuencias de datos de tipo T
* Post: Devuelve cierto si y sólo si ambos ficheros almacenan
* el mismo número de datos
*/ template <typename T>
bool igualLongitud (const char nombre1[], const char nombre2[]);
/*
* Pre: [f1] y [f2] están asociados a dos ficheros binarios que
* almacenan secuencias de datos de tipo T
* Post: Devuelve cierto si y sólo si los ficheros asociados a f1
* y f2 almacenan, en el momento de ser invocada esta
* función, un mismo número de datos no leídos
*/ template <typename T>
bool igualLongitud (ifstream& f1, ifstream& f2);
4
/*
* Pre: [nombre1] y [nombre2] son los nombres de dos ficheros
* binarios que almacenan secuencias de datos de tipo T
* Post: Devuelve cierto si y sólo si ambos ficheros almacenan
* el mismo número de datos
*/ template <typename T>
bool igualLongitud (const char nombre1[], const char nombre2[]) {
// Asocia los ficheros [nombre1] y [nombre2] a los flujos [f1] y [f2]
ifstream f1, f2;
f1.open(nombre1, ios::binary); f2.open(nombre2, ios::binary);
// Determina si ambos ficheros almacenan un número igual de datos
bool igual = igualLongitud <T> (f1, f2);
// Libera los ficheros asociados a los flujos [f1] y [f2]
f1.close(); f2.close();
// Devuelve el resultado de la comparación
return igual;
}
5
/*
* Pre: [f1] y [f2] están asociados a dos ficheros binarios que
* almacenan secuencias de datos de tipo T
* Post: Devuelve cierto si y sólo si los ficheros asociados a f1
* y f2 almacenan, en el momento de ser invocada esta
* función, un mismo número de datos no leídos
*/ template <typename T>
bool igualLongitud (ifstream& f1, ifstream& f2) {
T nuevo;
f1.read(reinterpret_cast<char *>(&nuevo), sizeof(T));
f2.read(reinterpret_cast<char *>(&nuevo), sizeof(T));
if (!f1.eof() && !f2.eof()) {
return igualLongitud <T> (f1, f2); // recurrencia
}
else {
return f1.eof() && f2.eof(); // base
}
}
6
Problema 2. Diseñar sin bucles:
/*
* Pre: [nombre] es un fichero binario que almacena una * secuencia de longitud no nula de datos de tipo T
* Post: Los valores de [menor] y [mayor] son iguales al menor
* y al mayor, respectivamente, de los datos almacenados * en el fichero [nombre]
*/ template <typename T>
void extremos (const char nombre[], T& menor, T& mayor);
7
/*
* Pre: [nombre] es un fichero binario que almacena una secuencia de
* longitud no nula de datos de tipo T
* Post: Los valores de [menor] y [mayor] son iguales al menor
* y al mayor, respectivamente, de los datos almacenados * en el fichero [nombre]
*/ template <typename T>
void extremos (const char nombre[], T& menor, T& mayor);
/*
* Pre: [f] es un flujo asociado a un fichero binario que almacena una * secuencia de longitud no nula de datos de tipo T y los valores * de [menor] y [mayor] son iguales a los de los datos leídos con
* menor valor y mayor valor, respectivamente.
* Post: Los valores de [menor] y [mayor] son iguales al menor
* y al mayor, respectivamente, de los datos almacenados * en el fichero asociado al flujo [f]
*/ template <typename T>
void extremos (ifstream& f, T& menor, T& mayor);
8
/*
* Pre: [nombre] es un fichero binario que almacena una * secuencia de longitud no nula de datos de tipo T
* Post: Los valores de [menor] y [mayor] son iguales al menor
* y al mayor, respectivamente, de los datos almacenados * en el fichero [nombre]
*/ template <typename T>
void extremos (const char nombre[], T& menor, T& mayor) {
// Asocia el ficheros binario [nombre] al flujo [f]
ifstream f;
f.open(nombre, ios::binary); // Asigna a [menor] y [mayor] el primer dato del fichero
f.read(reinterpret_cast<char *>(&menor), sizeof(T));
mayor = menor;
// Determina el menor y el mayor de los datos almacenados en el fichero
extremos <T> (f, menor, mayor);
// Libera el fichero asociado al flujo [f]
f.close();
}
9
/*
* Pre: [f] es un flujo asociado a un fichero binario que almacena una * secuencia de longitud no nula de datos de tipo T y los valores * de [menor] y [mayor] son iguales a los de los datos leídos con
* menor valor y mayor valor, respectivamente.
* Post: Los valores de [menor] y [mayor] son iguales al menor
* y al mayor, respectivamente, de los datos almacenados * en el fichero asociado al flujo [f]
*/ template <typename T>
void extremos (ifstream& f, T& menor, T& mayor) {
T nuevo;
f.read(reinterpret_cast<char *>(&nuevo), sizeof(T));
if (!f.eof()) {
if (nuevo < menor) { menor = nuevo; }
else if (mayor < nuevo) { mayor = nuevo; }
extremos <T> (f, menor, mayor);
}
}
10
Problema 3. Diseñar sin bucles:
/*
* Pre: [nombre] es un fichero binario que almacena una * secuencia de longitud no nula de datos de tipo T
* ordenada de menor a mayor valor
* Post: Los valores de [menor] y [mayor] son iguales al menor
* y al mayor, respectivamente, de los datos almacenados * en el fichero [nombre]
*/ template <typename T>
void extremosV2 (const char nombre[], T& menor, T& mayor);
11
/*
* Pre: [nombre] es un fichero binario que almacena una secuencia de * longitud no nula de datos de tipo T ordenada de menor a mayor valor
* Post: Los valores de [menor] y [mayor] son iguales al menor y al mayor, * respectivamente, de los datos almacenados en el fichero [nombre]
*/ template <typename T>
void extremosV2 (const char nombre[], T& menor, T& mayor);
/*
* Pre: [f] es un flujo asociado a un fichero binario que almacena una * secuencia de longitud no nula de datos de tipo T y el valor de
* [anterior] es igual al del último dato leído del fichero
* Post: Devuelve el último de los datos almacenados en el fichero
* asociado al flujo [f]
*/ template <typename T>
T ultimo (ifstream& f, T anterior);
12
/*
* Pre: [nombre] es un fichero binario que almacena una secuencia de * longitud no nula de datos de tipo T ordenada de menor a mayor valor
* Post: Los valores de [menor] y [mayor] son iguales al menor y al mayor, * respectivamente, de los datos almacenados en el fichero [nombre]
*/ template <typename T>
void extremosV2 (const char nombre[], T& menor, T& mayor) {
// Asocia el ficheros binario [nombre] al flujo [f]
ifstream f;
f.open(nombre, ios::binary); // Asigna a [menor] el primer dato del fichero
f.read(reinterpret_cast<char *>(&menor), sizeof(T));
// Asigna a [mayor] el último dato del fichero
mayor = ultimo <T> (f, menor);
// Libera el fichero asociado al flujo [f]
f.close();
}
13
/*
* Pre: [f] es un flujo asociado a un fichero binario que almacena una * secuencia de longitud no nula de datos de tipo T y el valor de
* [anterior] es igual al del último dato leído del fichero
* Post: Devuelve el último de los datos almacenados en el fichero
* asociado al flujo [f]
*/ template <typename T>
T ultimo (ifstream& f, T anterior) {
T nuevo;
f.read(reinterpret_cast<char *>(&nuevo), sizeof(T));
if (!f.eof()) { return ultimo <T> (f, nuevo); }
else {
return anterior; }
}
14
Problema 4. Diseñar sin bucles:
/*
* Pre: [nombre] es un fichero binario que almacena una * secuencia de datos de tipo T que cuenta, al menos, * con un dato menor que [limite]
* Post: Devuelve el primero de los datos almacenados en el
* fichero [nombre] cuyo valor es inferior al de [limite]
*/ template <typename T>
T primerMenor (const char nombre[], const T limite);
15
/*
* Pre: [nombre] es un fichero binario que almacena una secuencia * de datos de tipo T que cuenta, al menos, con un dato menor que * [limite]
* Post: Devuelve el primero de los datos almacenados en el fichero * [nombre] cuyo valor es inferior al de [limite]
*/ template <typename T>
T primerMenor (const char nombre[], const T limite);
/*
* Pre: [f] es un flujo asociado a un fichero binario que almacena una * secuencia de datos de tipo T que cuenta, al menos, con un dato
* menor que [limite]. No se ha leído ningún dato de fichero cuyo
* valor sea inferior al de [limite]
* Post: Devuelve el primero de los datos almacenados en el fichero
* asociado a [f] cuyo valor es inferior al de [limite]
*/ template <typename T>
T primerMenor (ifstream& f, const T limite);
16
/*
* Pre: [nombre] es un fichero binario que almacena una secuencia * de datos de tipo T que cuenta, al menos, con un dato menor que * [limite]
* Post: Devuelve el primero de los datos almacenados en el fichero * [nombre] cuyo valor es inferior al de [limite]
*/ template <typename T>
T primerMenor (const char nombre[], const T limite) {
// Asocia el ficheros binario [nombre] al flujo [f]
ifstream f;
f.open(nombre, ios::binary); // Asigna a [elPrimerMenor] el primer dato del fichero cuyo valor es // inferior al de [limite]
T elPrimerMenor;
elPrimerMenor = primerMenor <T> (f, limite);
// Libera el fichero asociado al flujo [f]
f.close();
// Devuelve el valor de [elPrimerMenor] return elPrimerMenor;
}
17
/*
* Pre: [f] es un flujo asociado a un fichero binario que almacena una * secuencia de datos de tipo T que cuenta, al menos, con un dato
* menor que [limite]. No se ha leído ningún dato de fichero cuyo
* valor sea inferior al de [limite]
* Post: Devuelve el primero de los datos almacenados en el fichero
* asociado a [f] cuyo valor es inferior al de [limite]
*/ template <typename T>
T primerMenor (ifstream& f, const T limite) {
T nuevo;
f.read(reinterpret_cast<char *>(&nuevo), sizeof(T));
if (nuevo < limite) { return nuevo;
}
else {
return primerMenor <T> (f, limite); }
}
18
Problema 5. Diseñar sin bucles:
/*
* Pre: [nombre] es un fichero binario que almacena una * secuencia de datos de tipo T, ordenada de menor a
* mayor valor, que cuenta, al menos, con un dato menor
* que [limite]
* Post: Devuelve el último de los datos almacenados en el
* fichero [nombre] cuyo valor es inferior al de [limite]
*/ template <typename T>
T ultimoMenor (const char nombre[], const T limite);
19
/*
* Pre: [nombre] es un fichero binario que almacena una secuencia de * datos de tipo T, , que cuenta, * al menos, con un dato menor que [limite]
* Post: Devuelve el último de los datos almacenados en el fichero * [nombre] cuyo valor es inferior al de [limite]
*/ template <typename T>
T ultimoMenor (const char nombre[], const T limite);
/*
* Pre: [f] es un flujo asociado a un fichero binario que almacena una * secuencia de datos de tipo T, ordenada de menor a mayor valor,
* que cuenta, al menos, con un dato menor que [limite]. El último * dato leído del fichero es igual a [ultimo] y su valor es inferior * al de [limite]
* Post: Devuelve el ultimo de los datos almacenados en el fichero
* asociado a [f] cuyo valor es inferior al de [limite]
*/ template <typename T>
T ultimoMenor (ifstream& f, const T limite, const T ultimo);
20
/*
* Pre: [nombre] es un fichero binario que almacena una secuencia de * datos de tipo T, ordenada de menor a mayor valor, que cuenta, * al menos, con un dato menor que [limite]
* Post: Devuelve el primero de los datos almacenados en el
* fichero [nombre] cuyo valor es inferior al de [limite]
*/ template <typename T>
T ultimoMenor (const char nombre[], const T limite) {
// Asocia el ficheros binario [nombre] al flujo [f]
ifstream f;
f.open(nombre, ios::binary); // Asigna a [primero] el valor del primer dato del fichero
T primero;
f.read(reinterpret_cast<char *>(&primero), sizeof(T));
T elUltimoMenor;
elUltimoMenor = ultimoMenor <T> (f, limite, primero);
f.close();
return elUltimoMenor;
}
21
/*
* Pre: [f] es un flujo asociado a un fichero binario que almacena una * secuencia de datos de tipo T, ordenada de menor a mayor valor,
* que cuenta, al menos, con un dato menor que [limite]. El último * dato leído del fichero es igual a [ultimo] y su valor es inferior * al de [limite]
* Post: Devuelve el ultimo de los datos almacenados en el fichero
* asociado a [f] cuyo valor es inferior al de [limite]
*/ template <typename T>
T ultimoMenor (ifstream& f, const T limite, const T ultimo) {
T nuevo;
f.read(reinterpret_cast<char *>(&nuevo), sizeof(T));
if (!f.eof()) {
if (nuevo < limite) { return ultimoMenor <T> (f, limite, nuevo); }
else { return ultimo; }
}
else { return ultimo; }
}
22
23
Descargar