Post on 17-Sep-2020
Programación 1
Tema V – Clase de problemas
Desarrollo de un módulo de biblioteca C++ para trabajar con conjuntos de letras
1
1. Representación del tipo ConjuntoDebe definirse la representación de los datos de tipo Conjuntoen el módulo conjunto presentado en la lección 17:
– Para ello se definirá un registro con uno o más campos:
struct Conjunto {
aquí se debe definir la estructura interna de un dato de tipo Conjunto y se debe explicar el significado y la forma de gestionar cada campo del registro
};
– La representación de un dato del tipo Conjunto deberá facilitar eldiseño algorítmico de las funciones asociadas al tipo y velar por laeficiencia de éstas.
2
Representación de un dato de tipo Conjunto:
/** Representación de un conjunto de letras del alfabeto (inglés):* elemento[0] <=> la letra ‘A’ pertenece al conjunto* elemento[1] <=> la letra ‘B’ pertenece al conjunto* ...* elemento['Y'‐'A'] <=> la letra ‘Y’ pertenece al conjunto* elemento['Z'‐'A'] <=> la letra ‘Z’ pertenece al conjunto*/
struct Conjunto {bool elemento['Z' ‐ 'A' + 1];
};
3
2. Diseño de las funciones del módulo Ahora deben especificarse cada una de las once funciones delmódulo conjunto presentadas en la lección 17 y, acontinuación, debe escribirse su código:
• Cada función se acompaña de una frase orientativa sobre sucomportamiento esperado. Se deben sustituir estas frases poruna especificación mucho más precisa, con su precondición ysu postcondición.
• Una vez especificada cada función, debe escribirse su códigoC++.
4
// para crear un conjunto vacío de letrasConjunto vacio ();
// para comprobar si una letra pertenece a un conjunto // de letrasbool pertenece (const Conjunto A, const char elemento);
// para incorporar una letra a un conjunto de letrasvoid incluir (Conjunto& A, const char elemento);
// para excluir una letra de un conjunto de letrasvoid excluir (Conjunto& A, const char elemento);
. . .
5
. . .
// para conocer cuántas letras pertenecen a un conjunto// de letrasint cardinal (const Conjunto A);
// para calcular la unión de dos conjuntos de letras Conjunto opUnion (const Conjunto A, const Conjunto B);
// para calcular la intersección de dos conjuntos de letras Conjunto opInterseccion (const Conjunto A, const Conjunto B);
// para calcular la diferencia de dos conjuntos de letras Conjunto opDiferencia (const Conjunto A, const Conjunto B);
. . .
6
. . .
// para mostrar por pantalla los elementos de un conjunto// de letras void mostrar (const Conjunto A);
// para almacenar una secuencia de conjuntos de letras// en un fichero, en formato binariovoid guardar (const char nombreFichero[],
const Conjunto T[], const int n);
// para leer una secuencia de conjuntos de letras// de un fichero que los almacena en formato binariobool recuperar (const char nombreFichero[],
Conjunto T[], int& n);
7
La función vacio():
// para crear un conjunto vacío de letrasConjunto vacio ();
Escribir la especificación y el código de la función vacio():
/** Pre: … su precondición …* Post: … su postcondición …*/Conjunto vacio () { … su código … }
8
La función vacio():
// para crear un conjunto vacío de letrasConjunto vacio ();
Especificación de la función vacio():
/** Pre: ‐‐‐* Post: Devuelve un conjunto vacío de letras */Conjunto vacio ();
9
Código de la función vacio():
/** Pre: ‐‐‐* Post: Devuelve un conjunto vacío de letras */Conjunto vacio () {
Conjunto C;for (char letra = 'A'; letra <= 'Z'; ++letra) {
C.elemento[letra ‐'A'] = false;}return C;
}
10
La función pertenece(A,elemento):
// para comprobar si una letra pertenece a un conjunto // de letrasbool pertenece (const Conjunto A, const char elemento);
Escribir la especificación y el código de la función pertenece(…):
/** Pre: … su precondición …* Post: … su postcondición …*/bool pertenece (const Conjunto A, const char elemento) {
… su código … }
11
La función pertenece(A,elemento):
// para comprobar si una letra pertenece a un conjunto // de letrasbool pertenece (const Conjunto A, const char elemento);
Especificación de la función pertenece(A,elemento):
/** Pre: elemento >= 'A' y elemento <= 'Z'* Post: Devuelve <true> si y solo si <elemento>* pertenece al conjunto <A>*/bool pertenece (const Conjunto A, const char elemento);
12
Código de la función pertenece(A,elemento):
/** Pre: elemento >= 'A' y elemento <= 'Z'* Post: Devuelve <true> si y solo si <elemento>* pertenece al conjunto <A>*/bool pertenece (const Conjunto A, const char elemento) {
return A.elemento[elemento‐'A'];}
13
La función incluir(A,elemento):
// para incorporar una letra a un conjunto de letrasvoid incluir (Conjunto& A, const char elemento);
Escribir la especificación y el código de la funciónincluir(A,elemento):
/** Pre: … su precondición …* Post: … su postcondición …*/void incluir (Conjunto& A, const char elemento) {
… su código … }
14
La función incluir(A,elemento):
// para incorporar una letra a un conjunto de letrasvoid incluir (Conjunto& A, const char elemento);
Especificación de la función incluir(A,elemento):
/** Pre: elemento >= 'A' y elemento <= 'Z'* Post: <elemento> pertenece al conjunto A junto a* todas las letras que pertenecían inicialmente * al conjunto <A> */void incluir (Conjunto& A, const char elemento);
15
Código de la función incluir(A,elemento):
/** Pre: elemento >= 'A' y elemento <= 'Z'* Post: <elemento> pertenece al conjunto A junto a* todas las letras que pertenecían inicialmente * al conjunto <A> */void incluir (Conjunto& A, const char elemento) {
A.elemento[elemento‐'A'] = true;}
16
La función excluir(A,elemento):
// para excluir una letra de un conjunto de letrasvoid excluir (Conjunto& A, const char elemento);
Escribir la especificación y el código de la funciónexcluir(A,elemento):
/** Pre: … su precondición …* Post: … su postcondición …*/void excluir (Conjunto& A, const char elemento);
17
La función excluir(A,elemento):
// para excluir una letra de un conjunto de letrasvoid excluir (Conjunto& A, const char elemento);
Especificación de la función excluir(A,elemento):
/** Pre: elemento >= 'A' y elemento <= 'Z'* Post: <elemento> no pertenece al conjunto A mientras* que restantes letras que pertenecían inicial‐* mente a <A> siguen perteneciendo y solo ellas*/void excluir (Conjunto& A, char elemento);
18
Código de la función excluir(A,elemento):
/** Pre: elemento >= 'A' y elemento <= 'Z'* Post: <elemento> no pertenece al conjunto A mientras* que restantes letras que pertenecían inicial‐* mente a <A> siguen perteneciendo y solo ellas*/void excluir (Conjunto& A, char elemento) {
A.elemento[elemento‐'A'] = false;}
19
La función cardinal(A):
// para conocer cuántas letras pertenecen a un conjunto// de letrasint cardinal (const Conjunto A);
Escribir la especificación y el código de la función cardinal(A):
/** Pre: … su precondición …* Post: … su postcondición …*/int cardinal (const Conjunto A);
20
La función cardinal(A):
// para conocer cuántas letras pertenecen a un conjunto// de letrasint cardinal (const Conjunto A);
Especificación de la función cardinal(A):
/** Pre: ‐‐* Post: Devuelve el número de elementos del conjunto <A>*/int cardinal (const Conjunto A);
21
Código de la función cardinal(A):
/** Pre: ‐‐‐* Post: Devuelve el número de elementos del conjunto <A>*/int cardinal (const Conjunto A) {
int cuenta = 0;for (char letra = 'A'; letra <= 'Z'; ++letra) {
if (A.elemento[letra ‐'A']) { cuenta = cuenta + 1;
}}return cuenta;
}
22
La función opUnion(A,B):
// para calcular la unión de dos conjuntos de letras Conjunto opUnion (const Conjunto A, const Conjunto B);
Escribir la especificación y el código de la función opUnion(A,B):
/** Pre: … su precondición …* Post: … su postcondición …*/Conjunto opUnion (const Conjunto A, const Conjunto B) {
… su código … }
23
La función opUnion(A,B):
// para calcular la unión de dos conjuntos de letras Conjunto opUnion (const Conjunto A, const Conjunto B);
Especificación de la función opUnion(A,B):
/** Pre: ‐‐‐* Post: Devuelve la unión de los conjuntos <A> y <B>*/Conjunto opUnion (const Conjunto A, const Conjunto B);
24
Código de la función opUnion(A,B):
/** Pre: ‐‐‐* Post: Devuelve la unión de los conjuntos <A> y <B>*/Conjunto opUnion (const Conjunto A, const Conjunto B) {
Conjunto C;for (int i = 0; i <= 'Z'‐'A'; ++i) {
C.elemento[i] = A.elemento[i] || B.elemento[i];}return C;
}
25
La función opInterseccion(A,B):
// para calcular la intersección de dos conjuntos de // letras Conjunto opInterseccion (const Conjunto A,
const Conjunto B);
Escribir la especificación y el código de la funciónopInterseccion(A,B):
/** Pre: … su precondición …* Post: … su postcondición …*/Conjunto opInterseccion (const Conjunto A,
const Conjunto B) { su código }26
La función opInterseccion(A,B):
// para calcular la intersección de dos conjuntos de // letras Conjunto opInterseccion (const Conjunto A,
const Conjunto B);
Especificación de la función opInterseccion(A,B):
/** Pre: ‐‐‐* Post: Devuelve la intersección de los conjuntos <A> y <B>
*/Conjunto opInterseccion (const Conjunto A,
const Conjunto B);27
Código de la función opInterseccion(A,B):
/** Pre: ‐‐‐* Post: Devuelve la intersección de los conjuntos <A>* y <B>*/Conjunto opInterseccion (const Conjunto A,
const Conjunto B) {Conjunto C;for (int i = 0; i <= 'Z'‐'A'; ++i) {
C.elemento[i] = A.elemento[i] && B.elemento[i];}return C;
}
28
La función opDiferencia(A,B):
// para calcular la diferencia de dos conjuntos de letras Conjunto opDiferencia (const Conjunto A, const Conjunto B);
Escribir la especificación y el código de la funciónopDiferencia(A,B):
/** Pre: … su precondición …* Post: … su postcondición …*/Conjunto opDiferencia (const Conjunto A, const Conjunto B) {
… su código … }
29
La función opDiferencia(A,B):
// para calcular la diferencia de dos conjuntos de letras Conjunto opDiferencia (const Conjunto A, const Conjunto B);
Especificación de la función opDiferencia(A,B):
/** Pre: ‐‐‐* Post: Devuelve el conjunto diferencia A ‐ B*/Conjunto opDiferencia (const Conjunto A, const Conjunto B);
30
Código de la función opDiferencia(A,B):
/** Pre: ‐‐‐* Post: Devuelve el conjunto diferencia A ‐ B*/Conjunto opDiferencia (const Conjunto A,
const Conjunto B) {Conjunto C;for (int i = 0; i <= 'Z'‐'A'; ++i) {
C.elemento[i] = A.elemento[i] && !B.elemento[i]; }return C;
}
31
La función mostrar(A):
// para mostrar por pantalla los elementos de un conjunto// de letras void mostrar (const Conjunto A);
Escribir la especificación y el código de la función mostrar(A):
/** Pre: … su precondición …* Post: … su postcondición …*/void mostrar (const Conjunto A) { … su código … }
32
La función mostrar(A):
// para mostrar por pantalla los elementos de un conjunto// de letras void mostrar (const Conjunto A);
Especificación de la función mostrar(A):
/** Pre: ‐‐* Post: Presenta por pantalla, en una línea, los* elementos del conjunto <A> con el siguiente* formato:* { D, F, J, M, N, Q, S, Z }*/void mostrar (Conjunto A);
33
Código de la función mostrar(A):
/** Pre: ‐‐* Post: Presenta por pantalla, en una línea, los elementos * del conjunto <A> con el siguiente formato:* { D, F, J, M, N, Q, S, Z }*/
void mostrar (Conjunto A) {int cuenta = 0;for (int i = 0; i <= 'Z' ‐ 'A'; ++i) {
if (A.elemento[i]) {cuenta = cuenta + 1;if (cuenta == 1) { cout << "{ " << char ('A' + i); }else { cout << ", " << char ('A' + i); }
}}if (cuenta == 0) { cout << "{}" << endl; }else { cout << " }" << endl; }
} 34
La función guardar(nombreFichero,T,n):
// para almacenar una secuencia de conjuntos de letras// en un fichero, en formato binariovoid guardar (const char nombreFichero[],
const Conjunto T[], const int n);
Escribir la especificación y el código de la función guardar(…):
/* Pre: … su precondición …* Post: … su postcondición … */void guardar (const char nombreFichero[],
const Conjunto T[], const int n) { … su código …
}35
La función guardar(nombreFichero,T,n):
// para almacenar una secuencia de conjuntos de letras// en un fichero, en formato binariovoid guardar (const char nombreFichero[],
const Conjunto T[], const int n);
Especificación de la función guardar(nombreFichero,T,n):
/** Pre: ‐‐‐* Post: Crea un fichero de nombre <nombreFichero> y escribe en* él la secuencia de datos binarios almacenada en T[0,n‐1]*/
void guardar (const char nombreFichero[], const Conjunto T[],const int n);
36
Código de la función guardar(nombreFichero,T,n):
/** Pre: ‐‐‐* Post: Crea un fichero de nombre <nombreFichero> y escribe en* él la secuencia de datos binarios almacenada en T[0,n‐1]*/
void guardar (const char nombreFichero[], const Conjunto T[],const int n) {
ofstream f; f.open(nombreFichero, ios::binary); for (int i = 0; i < n; ++i) {
// Escribe el conjunto T[i] en el ficherof.write(reinterpret_cast<char *>(&T[i]), sizeof(Conjunto));
}f.close(); // Libera el fichero y lo disocia del flujo
}
37
La función recuperar(nombreFichero,T,n):
// para leer una secuencia de conjuntos de letras// de un fichero que los almacena en formato binariobool recuperar (const char nombreFichero[],
Conjunto T[], int& n);
Escribir la especificación y el código de la función La funciónrecuperar(…):
/** Pre: … su precondición …* Post: … su postcondición …*/bool recuperar (const char nombreFichero[],
Conjunto T[], int& n) { … su código … }38
La función recuperar(nombreFichero,T,n):
// para leer una secuencia de conjuntos de letras// de un fichero que los almacena en formato binariobool recuperar (const char nombreFichero[],
Conjunto T[], int& n);
Especificación de la función recuperar(nombreFichero,T,n):
/** Pre: <nombreFichero> es el nombre de un fichero que ...* Post: Devuelve <false> si no es posible leer la ...*/
bool recuperar (const char nombreFichero[], Conjunto T[], int& n);
39
Especificación de la función recuperar(nombreFichero,T,n):
/** Pre: <nombreFichero> es el nombre de un fichero que almacena* una secuencia de datos binarios de tipo <Conjunto>* Post: Devuelve <false> si no es posible leer la información* del fichero <nombreFichero>. Si es posible, asigna a <n> * el número de conjuntos que almacena el fichero, * asigna a los elementos de T[0,n‐1] los <n> datos de tipo * <Conjunto> almacenados en el fichero y devuelve <true>.*/
bool recuperar (const char nombreFichero[], Conjunto T[], int& n);
40
Código de la función recuperar(nombreFichero,T,n):
/** Pre: <nombreFichero> es el nombre de un fichero que almacena ...* Post: Devuelve <false> si no es posible leer la información ...*/
bool recuperar (const char nombreFichero[], Conjunto T[], int& n) {ifstream f; f.open(nombreFichero, ios::binary);n = 0;if (f.is_open()) {
f.read(reinterpret_cast<char *>(&T[n]),sizeof(Conjunto));while (!f.eof()) {
n = n + 1 ;f.read(reinterpret_cast<char *>(&T[n]),sizeof(Conjunto));
}f.close(); return true;
}else { return false; }
} 41
42