Sei sulla pagina 1di 54

Programación 1

Desarrollo de proyectos de 
programación

Desarrollo de un módulo
de biblioteca C++ para trabajar con 
multiconjuntos de números primos

1
1. Representación del tipo Multiconjunto
• Debe definirse la representación de los datos de tipo Multiconjunto
que representan un multiconjunto al que pueden pertenecer
exclusivamente de los primeros NUM_PRIMOS números primos (2, 3, 5,
7, 9, 11, 13, 17, 19, 23, 29, etc.) :
– Se definirá la constante entera NUM_PRIMOS. Por ejemplo:

cont int NUM_PRIMOS= 25;

– Se definirá el tipo Multiconjunto como un registro con uno o más


campos:

struct Multiconjunto {
. . .
};

– La definición del tipo Multiconjunto 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 Multiconjunto:

/*
* Se van a definir multiconjuntos a los que pueden pertenecer 
* exclusivamente los NUM_PRIMOS primeros números primos
*/
const int NUM_PRIMOS = 25;

/*
* Representa un multiconjunto al que pueden pertenecer, 
* exclusivamente, los NUM_PRIMOS primeros números primos:
*    multiplicidad[0]: su valor es la multiplicidad del 2 (primo núm. 1)
*    multiplicidad[1]: su valor es la multiplicidad del 3 (primo núm. 2)
*    multiplicidad[2]: su valor es la multiplicidad del 5 (primo núm. 3)
*    multiplicidad[3]: su valor es la multiplicidad del 7 (primo núm. 4)
*    multiplicidad[4]: su valor es la multiplicidad del 11 (primo núm. 5)
*        . .. 
*/
struct Multiconjunto {
int multiplicidad[NUM_PRIMOS];
};

3
/* 
* Fichero multiconjunto.cc de implementación del módulo 
* multiconjunto 
*/

#include <iostream>
#include <iomanip>
#include <fstream>
#include "multiconjunto.h"

using namespace std;

/* Almacena los NUM_PRIMOS primeros números primos  */ 
const int PRIMOS[] = { 
2,  3,  5,  7, 11, 13, 17, 19, 23, 29,  
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,  
73, 79, 83, 89, 97 
};
4
2. Diseño de las funciones del módulo  
En primer lugar deben especificarse cada una de las catorce
funciones del módulo multiconjunto, 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
el código C++ del fichero de implementación del módulo
multiconjunto que incluirá el código de las catorce funciones.
Sugerencia: Definir en el fichero de implementación un vector
constante que almacene los NUM_PRIMOS primeros números
primos.

5
Presentación informal de las funciones que permiten crear y
modificar un multiconjunto de números primos:

// para crear un multiconjunto sin ningún elemento
Multiconjunto vacio ();

// para incorporar un número primo m‐veces a un multiconjunto
void incluir (Multiconjunto& A, const int p, const int m);

// para incorporar un número primo una vez a un multiconjunto
void incluir (Multiconjunto& A, const int p);

// para retirar m‐items de un número primo de un multiconjunto
void retirar (Multiconjunto& A, const int p, const int m);

// para retirar todos los items de un número primo de un 
// multiconjunto
void eliminar (Multiconjunto& A, const int p);

. . .
6
Presentación informal de las funciones para consultar la
información de un multiconjunto de números primos:

. . .

// para saber la multiplicidad de un número primo en un 
// multiconjunto 
int multiplicidad (const Multiconjunto A, const int p);

// para saber el número total de elementos de un multiconjunto
int cardinalidad (const Multiconjunto A);

// para saber el número total de elementos diferentes de un
// multiconjunto
int numDiferentes (const Multiconjunto A);

// para presentar por pantalla el contenido de un multiconjunto
int mostrar (const Multiconjunto A);

. . .
7
Presentación informal de las funciones para operar con
multiconjuntos de números primos:

. . . 

// para calcular la unión de dos multiconjuntos 
Multiconjunto opUnion (const Multiconjunto A, 
const Multiconjunto B);

// para calcular la intersección de dos multiconjuntos 
Multiconjunto opInterseccion (const Multiconjunto A, 
const Multiconjunto B);

// para calcular la diferencia de dos multiconjuntos 
Multiconjunto opDiferencia (const Multiconjunto A, 
const Multiconjunto B);

. . .

8
Presentación informal de las funciones para almacenar
multiconjuntos de números primos en un fichero binario y
recuperar de él la secuencia de multiconjuntos de números
primos almacenada en él previamente:

. . .

// para almacenar la información de una colección de
// multiconjuntos en un fichero binario
void guardar (const char nombreFichero[], 
const Multiconjunto T[], const int n);

// para recuperar la información de una colección de
// multiconjuntos almacenada en un fichero binario
bool recuperar (const char nombreFichero[], 
Multiconjunto T[], int& n); 

9
La función vacio():

// para crear un multiconjunto sin ningún elemento
Multiconjunto vacio ();

Escribir la especificación y el código de la función vacio():

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
Multiconjunto vacio () { … su código …  }

10
La función vacio():

// para crear un multiconjunto sin ningún elemento
Multiconjunto vacio ();

Especificación de la función vacio():

/*
* Pre: ‐‐‐
* Post: Devuelve un multiconjunto vacío de los primeros 
*       NUM_PRIMOS números primos
*/
Multiconjunto vacio ();

11
Código de la función vacio():

/*
* Pre: ‐‐‐
* Post: Devuelve un multiconjunto vacío de los primeros 
*       NUM_PRIMOS números primos
*/
Multiconjunto vacio () {
Multiconjunto mc;
for (int i = 0; i < NUM_PRIMOS; ++i) {
mc.multiplicidad[i] = 0;
}
return mc;
}

12
La función incluir(A,p,m):

// para incorporar un número primo m‐veces a un
// multiconjunto
void incluir (Multiconjunto& A, const int p, const int m);

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


incluir(A,p,m):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
void incluir (Multiconjunto& A, const int p, const int m) {
… su código …
} 13
La función incluir(A,p,m):

// para incorporar un número primo m‐veces a un
// multiconjunto
void incluir (Multiconjunto& A, const int p, const int m);

Especificación de la función incluir(A,p,m):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números
*      primos y m>=1
* Post: Mantiene los elementos iniciales de A e
*       incorpora m‐items del número primo p
*/
void incluir (Multiconjunto& A, const int p, 
const int m);
14
Código de la función incluir(A,p,m):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números
*      primos y m>=1
* Post: Mantiene los elementos iniciales de A e
*       incorpora m‐items del número primo p
*/
void incluir (Multiconjunto& A, const int p, 
const int m) {
int i = buscar(p);
A.multiplicidad[i] = A.multiplicidad[i] + m;
}

15
Un primer diseño de la función auxiliar buscar(p):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números primos
* Post: Devuelve el número de orden de p en la relación de
*       números primos 2, 3, 5, 7, 11, 13, etc. contando a 
*       partir de 0 (el número de orden del 2 es el 0, el 
*       del 3 es el 1, el del 5 es el 2, el del 7 es el 3
*       y así sucesivamente) 
*/
int buscar (const int p) {
int i = 0;
while (PRIMOS[i]!=p && i < NUM_PRIMOS) { i = i + 1; }
return i;

16
Diseño más eficiente de la función auxiliar buscar(p):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números primos
* Post: Devuelve el número de orden de p en la relación de números
*       primos 2, 3, 5, 7, 11, 13, etc. contando a partir de 0 
*       (el número de orden del 2 es el 0, el del 3 es el 1, el
*       del 5 es el 2, el del 7 es el 3 y así sucesivamente) 
*/
int buscar (const int p) {
int inf = 0, sup = NUM_PRIMOS ‐ 1;
while (inf!=sup) { 
int medio = (inf + sup) / 2;
if (PRIMOS[medio]<p) { inf = medio + 1; }
else { sup = medio; }
}
return inf;

17
La función incluir(A,p):

// para incorporar un número primo una vez a un 
// multiconjunto
void incluir (Multiconjunto& A, const int p);

Escribir la especificación y el código de la función incluir(A,p):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
void incluir (Multiconjunto& A, const int p) { 
… su código …  
}
18
La función incluir(A,p):

// para incorporar un número primo una vez a un 
// multiconjunto
void incluir (Multiconjunto& A, const int p);

Especificación de la función incluir(A,p):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números primos 
* Post: Mantiene los elementos iniciales de A e incorpora
*       un item del número primo p
*/
void incluir (Multiconjunto& A, const int p);

19
Código de la función incluir(A,p):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números primos 
* Post: Mantiene los elementos iniciales de A e incorpora
*       un item del número primo p
*/
void incluir (Multiconjunto& A, const int p) {
incluir(A,p,1);
}

20
La función retirar(A,p,m):

// para retirar m‐items de un número primo de un 
// multiconjunto
void retirar (Multiconjunto& A, const int p, 
const int m);

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


retirar(A,p,m):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
void retirar (Multiconjunto& A, const int p, 
const int m) { … su código …  } 21
La función retirar(A,p,m):

// para retirar m‐items de un número primo de un 
// multiconjunto
void retirar (Multiconjunto& A, const int p, 
const int m);

Especificación de la función retirar(A,p,m):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números primos
*      y m > 0 
* Post: Retira de A m items del número primo p y mantiene
*       los restantes elementos iniciales de A
*/
void retirar (Multiconjunto& A, const int p, 
const int m); 22
Código de la función retirar(A,p,m):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números primos
*      y m > 0 
* Post: Retira de A m items del número primo p y mantiene
*       los restantes elementos iniciales de A
*/
void retirar (Multiconjunto& A, const int p, 
const int m) {
int i = buscar(p);
if (A.multiplicidad[i] >= m) {
A.multiplicidad[i] = A.multiplicidad[i] ‐ m;
}
else {  A.multiplicidad[i] = 0;  }
}
23
La función eliminar(A,p):

// para retirar todos los items de un número primo de un 
// multiconjunto
void eliminar (Multiconjunto& A, const int p);

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


eliminar(A,p):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
void eliminar (Multiconjunto& A, const int p)  {
… su código …  

24
La función eliminar(A,p):

// para retirar todos los items de un número primo de un 
// multiconjunto
void eliminar (Multiconjunto& A, const int p);

Especificación de la función eliminar(A,p):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números 
*      primos 
* Post: Retira de A todos los items del número
*       primo p y mantiene los restantes elementos
*       iniciales de A
*/
void eliminar (Multiconjunto& A, const int p);
25
Código de la función eliminar(A,p):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números 
*      primos 
* Post: Retira de A todos los items del número
*       primo p y mantiene los restantes elementos
*       iniciales de A
*/
void eliminar (Multiconjunto& A, const int p) {
A.multiplicidad[buscar(p)] = 0;
}

26
La función multiplicidad(A,p):

// para saber la multiplicidad de un número primo en un 
// multiconjunto
int multiplicidad (const Multiconjunto A, const int p);

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


multiplicidad(A,p):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
int multiplicidad (const Multiconjunto A, const int p) {
… su código …  
}
27
La función multiplicidad(A,p):

// para saber la multiplicidad de un número primo en un 
// multiconjunto 
int multiplicidad (const Multiconjunto A, const int p);

Especificación de la función multiplicidad(A,p):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números 
*      primos
* Post: Devuelve la multiplicidad de p en el multicon‐
*       junto A
*/
int multiplicidad (const Multiconjunto A, const int p);
28
Código de la función multiplicidad(A,p):

/*
* Pre: p es uno de los NUM_PRIMOS primeros números 
*      primos
* Post: Devuelve la multiplicidad de p en el multicon‐
*       junto A
*/
int multiplicidad (const Multiconjunto A, const int p) {
return A.multiplicidad[buscar(p)];
}

29
La función cardinalidad(A):

// para saber el número total de elementos de un 
// multiconjunto
int cardinalidad (const Multiconjunto A);

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


cardinalidad(A):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
int cardinalidad (const Multiconjunto A) { … su código …  }

30
La función cardinalidad(A):

// para saber el número total de elementos de un 
// multiconjunto
int cardinalidad (const Multiconjunto A);

Especificación de la función cardinalidad(A):

/*
* Pre: ‐‐‐
* Post: Devuelve el número total de elementos del 
*       multiconjunto A, es decir, la suma de las 
*       multiplicidades de todos sus elementos
*/
int cardinalidad (const Multiconjunto A);
31
Código de la función cardinalidad(A):

/*
* Pre: ‐‐‐
* Post: Devuelve el número total de elementos del 
*       multiconjunto A, es decir, la suma de las 
*       multiplicidades de todos sus elementos
*/
int cardinalidad (const Multiconjunto A) {
int total = 0;
for (int i = 0; i < NUM_PRIMOS; ++i) {
total = total + A.multiplicidad[i];
}
return total;
}

32
La función numDiferentes(A):

// para saber el número total de elementos diferentes
// de un multiconjunto
int numDiferentes (const Multiconjunto A);

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


numDiferentes(A):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
int numDiferentes (const Multiconjunto A) { … su código …  }
33
La función numDiferentes(A):

// para saber el número total de elementos diferentes
// de un multiconjunto
int numDiferentes (const Multiconjunto A);

Especificación de la función numDiferentes(A):

/*
* Pre: ‐‐‐
* Post: Devuelve el número de elementos diferentes de 
*       multiconjunto A
*/
int numDiferentes (const Multiconjunto A);

34
Código de la función numDiferentes(A):

/*
* Pre: ‐‐‐
* Post: Devuelve el número de elementos diferentes de 
*       multiconjunto A
*/
int numDiferentes (const Multiconjunto A) {
int total = 0;
for (int i = 0; i < NUM_PRIMOS; ++i) {
if (A.multiplicidad[i]>0) { total = total + 1; }
}
return total;
}

35
La función mostrar(A):

// para presentar por pantalla el contenido de un 
// multiconjunto
int mostrar (const Multiconjunto A);

Escribir la especificación y el código de la función mostrar(A):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
int mostrar (const Multiconjunto A) { … su código …  }

36
La función mostrar(A):

// para presentar por pantalla el contenido de un 
// multiconjunto
int mostrar (const Multiconjunto A);

Especificación de la función mostrar(A):

/*
* Pre: ‐‐
* Post: Presenta por pantalla, en una línea, los 
*       elementos de A
*/
void mostrar (const Multiconjunto A) 

37
Código de la función mostrar(A):
/*
* Pre: ‐‐
* Post: Presenta por pantalla, en una línea, los elementos de A
*/
void mostrar (const Multiconjunto A) {
int cuenta = 0;
for (int i = 0; i < NUM_PRIMOS; ++i) {
if (A.multiplicidad[i]>0) {
cuenta = cuenta + 1;
if (cuenta==1) { 
if (A.multiplicidad[i]==1) { cout << "{ " << PRIMOS[i]; }
else { cout << "{ " << PRIMOS[i] << "(" << A.multiplicidad[i] << ")"; }
}
else { 
if (A.multiplicidad[i]==1) { cout << ", " << PRIMOS[i]; }
else { cout << ", " << PRIMOS[i] << "(" << A.multiplicidad[i] << ")"; }
}
}
}
if (cuenta==0) { cout << "{}" << endl; }
else { cout << " }" << endl; }
}
38
La función opUnion(A,B):

// para calcular la unión de dos multiconjuntos 
Multiconjunto opUnion (const Multiconjunto A, 
const Multiconjunto B);

Escribir la especificación y el código de la función opUnion(A,B):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
Multiconjunto opUnion (const Multiconjunto A, 
const Multiconjunto B) { … su código …  }

39
La función opUnion(A,B):

// para calcular la unión de dos multiconjuntos 
Multiconjunto opUnion (const Multiconjunto A, 
const Multiconjunto B);

Especificación de la función opUnion(A,B):

/*
* Pre: ‐‐‐
* Post: Devuelve la unión de los multiconjuntos A y B
*/
Multiconjunto opUnion (const Multiconjunto A, 
const Multiconjunto B);

40
Código de la función opUnion(A,B):

/*
* Pre: ‐‐‐
* Post: Devuelve la unión de los multiconjuntos A y B
*/
Multiconjunto opUnion (const Multiconjunto A, 
const Multiconjunto B) {
Multiconjunto mc;
for (int i = 0; i < NUM_PRIMOS; ++i) {
mc.multiplicidad[i] = A.multiplicidad[i] 
+ B.multiplicidad[i];
}
return mc;
}

41
La función opInterseccion(A,B):

// para calcular la intersección de dos multiconjuntos 
Multiconjunto opInterseccion (const Multiconjunto A, 
const Multiconjunto B);

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


opInterseccion(A,B):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
Multiconjunto opInterseccion (const Multiconjunto A, 
const Multiconjunto B) { … su código …  }
42
La función opInterseccion(A,B):

// para crear una cola sin ningún ciudadano
ColaC nuevaColaC();

Especificación de la función opInterseccion(A,B):

/*
* Pre: ‐‐‐
* Post: Devuelve la intersección de los multiconjun‐
*       tos A y B
*/
Multiconjunto opInterseccion (const Multiconjunto A, 
const Multiconjunto B);

43
Código de la función opInterseccion(A,B):

/*
* Pre: ‐‐‐
* Post: Devuelve la intersección de los multiconjuntos A y B
*/
Multiconjunto opInterseccion (const Multiconjunto A, 
const Multiconjunto B) {
Multiconjunto mc;
for (int i = 0; i < NUM_PRIMOS; ++i) {
if (A.multiplicidad[i]<=B.multiplicidad[i]) {
mc.multiplicidad[i] = A.multiplicidad[i];
}
else { mc.multiplicidad[i] = B.multiplicidad[i]; }
}
return mc;
}
44
La función opDiferencia(A,B):

// para calcular la diferencia de dos multiconjuntos 
Multiconjunto opDiferencia (const Multiconjunto A, 
const Multiconjunto B);

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


opDiferencia(A,B):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
Multiconjunto opDiferencia (const Multiconjunto A, 
const Multiconjunto B) { … su código …  }
45
La función opDiferencia(A,B):

// para calcular la diferencia de dos multiconjuntos 
Multiconjunto opDiferencia (const Multiconjunto A, 
const Multiconjunto B);

Especificación de la opDiferencia(A,B):

/*
* Pre: ‐‐‐
* Post: Devuelve la diferencia de los multiconjuntos A y B
*/
Multiconjunto opDiferencia (const Multiconjunto A, 
const Multiconjunto B);

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

/*
* Pre: ‐‐‐
* Post: Devuelve la diferencia de los multiconjuntos A y B
*/
Multiconjunto opDiferencia (const Multiconjunto A, 
const Multiconjunto B) {
Multiconjunto mc;
for (int i = 0; i < NUM_PRIMOS; ++i) {
if (A.multiplicidad[i]>B.multiplicidad[i]) {
mc.multiplicidad[i] = A.multiplicidad[i] 
‐ B.multiplicidad[i];
}
else { mc.multiplicidad[i] = 0; } 
}
return mc;
} 47
La función guardar(nombreFichero,T,n):

// para almacenar la información de una colección de
// multiconjuntos en un fichero binario
void guardar (const char nombreFichero[], 
const Multiconjunto T[], const int n);

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


guardar(nombreFichero,T,n):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
void guardar (const char nombreFichero[], 
const Multiconjunto T[], const int n) { … su código …  }
48
La función guardar(nombreFichero,T,n):

// para almacenar la información de una colección de
// multiconjuntos en un fichero binario
void guardar (const char nombreFichero[], 
const Multiconjunto 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 de tipo Multi‐
*       conjunto almacenada en T[0,n‐1]
*/
void guardar (const char nombreFichero[], 
const Multiconjunto T[], const int n);
49
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 de tipo Multiconjunto almacenada 
*       en T[0,n‐1]
*/
void guardar (const char nombreFichero[], const Multiconjunto T[],
const int n) {
ofstream f;
f.open(nombreFichero, ios::binary); 
for (int i = 0; i < n; ++i) {
/*  Escribe el multiconjunto T[i] en el fichero */
f.write(reinterpret_cast<char *>(&T[i]), sizeof(Multiconjunto)); 
}
f.close();           // Libera el fichero y lo disocia del flujo   
}    

50
La función recuperar(nombreFichero,T,n):

// para recuperar la información de una colección de
// multiconjuntos almacenada en un fichero binario
bool recuperar (const char nombreFichero[], 
Multiconjunto T[], int& n); 

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


recuperar(nombreFichero,T,n):

/*
* Pre: … su precondición …
* Post: … su postcondición …
*/
bool recuperar (const char nombreFichero[], 
Multiconjunto T[], int& n) { … su código …  }
51
Especificación de recuperar(nombreFichero,T,n):

/*
* Pre: nombreFichero es el nombre de un fichero que almacena
*      una secuencia de datos binarios de tipo Multiconjunto
* 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 T[0,n‐1] los n de datos de
*       tipo Multiconjunto almacenados en el fichero y
*       devuelve true.
*/
bool recuperar (char nombreFichero[], 
Multiconjunto T[], int& n); 

52
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[], 
Multiconjunto T[], int& n) {
ifstream f; 
n = 0;
f.open(nombreFichero, ios::binary); 
if (f.is_open()) {
while (!f.eof()) {
f.read(reinterpret_cast<char *>(&T[n]), sizeof(Multiconjunto));
if (!f.eof()) { n = n + 1 ; }
}
f.close();  return true;
}
else { return false; }
}
53
54

Potrebbero piacerti anche