Вы находитесь на странице: 1из 42

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 Conjunto
Debe definirse la representación de los datos de tipo Conjunto, 
definido en el módulo conjunto, que representan un conjunto 
de letras del alfabeto (inglés):
– Para ello se definirá un registro con uno o más campos:

struct Conjunto {

… Escribir aquí los campos del registro …

};

– La representación de un dato del tipo Conjunto deberá facilitar el


diseño algorítmico de las operaciones asociadas al tipo y velar por la
eficiencia 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  
En primer lugar deben especificarse cada una de las once
funciones del módulo conjunto, que se detallan a
continuación, junto con una frase orientativa sobre su
comportamiento esperado. Se recuerda que cada especificación
exige una precondición y una postcondición.
Después de haber sido especificada cada función, debe
escribirse su código C++.

4
// para crear un conjunto vacío de letras
Conjunto vacio ()

// para comprobar si una letra pertenece a un conjunto 
// de letras
bool pertenece (const Conjunto A, const char elemento);

// para incorporar una letra a un conjunto de letras
void incluir (Conjunto& A, const char elemento);

// para excluir una letra de un conjunto de letras
void excluir (Conjunto& A, const char elemento);

. . .

5
. . .

// para conocer cuántas letras pertenecen a un conjunto
// de letras
int 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 binario
void 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 binario
bool recuperar (const char nombreFichero[], 
Conjunto T[], int& n);

7
La función vacio():

// para crear un conjunto vacío de letras
Conjunto 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 letras
Conjunto 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 (int i = 0; i < 'Z'‐'A'+1; ++i) {
C.elemento[i] = false;
}
return C;
}

10
La función pertenece(A,elemento):

// para comprobar si una letra pertenece a un conjunto 
// de letras
bool 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 letras
bool 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 letras
void incluir (Conjunto& A, const char elemento);

Escribir la especificación y el código de la función


incluir(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 letras
void 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 letras
void excluir (Conjunto& A, const char elemento);

Escribir la especificación y el código de la función


excluir(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 letras
void 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 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 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 letras
int 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 letras
int 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 (int i = 0; i < 'Z'‐'A'+1; ++i) {
if (A.elemento[i]) { 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'+1; ++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ón


opInterseccion(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'+1; ++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ón


opDiferencia(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 la diferencia de los conjuntos A y B
*/
Conjunto opDiferencia (const Conjunto A, 
const Conjunto B);

30
Código de la función opDiferencia(A,B):

/*
* Pre: ‐‐‐
* Post: Devuelve la diferencia de los conjuntos A y B
*/
Conjunto opDiferencia (const Conjunto A, 
const Conjunto B) {
Conjunto C;
for (int i = 0; i < 'Z'‐'A'+1; ++i) {
if (A.elemento[i] && !B.elemento[i]) { 
C.elemento[i] = true; 
}
else { C.elemento[i] = false; }
}
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'+1; ++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 binario
void 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 binario
void 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 fichero */
f.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 binario
bool recuperar (const char nombreFichero[], 
Conjunto T[], int& n);

Escribir la especificación y el código de la función La función


recuperar(…):

/*
* 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 binario
bool 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 almacena ...
* Post: Devuelve false si no es posible leer la información ...
*/
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()) {
while (!f.eof()) {
f.read(reinterpret_cast<char*>(&T[n]),sizeof(Conjunto));
if (!f.eof()) { n = n + 1 ; }
}
f.close();  return true;
}
else { return false; }
} 41
42