Programación 1 Tema V – Clase de...

Preview:

Citation preview

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

Recommended