programación iivicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.escriba un programa...

48
Programación II Relación de Ejercicios Sonido e Imagen UNIVERSIDAD DE MÁLAGA Dpto. Lenguajes y CC. Computación E.T.S.I. Telecomunicación Contenido Tema 1: Almacenamiento en Memoria Secundaria. Ficheros 2 Tema 2: Tipos Abstractos de Datos 3 Tema 2.1: Programacion Modular ................................ 3 Tema 2.2: Tipos Abstractos de Datos .............................. 4 Tema 3: Gestión de Memoria Dinámica 8 Tema 3.1: Listas Enlazadas ................................... 8 Tema 3.2: Abstracción en la Gestión de Memoria Dinámica ................. 10 Tema 4: Introducción a la Programación Orientada a Objetos 16 Tema 5: Colecciones 24 Prácticas de Laboratorio 25 Práctica 1: Almacenamiento Persistente de Datos ....................... 25 Práctica 2: Tipos Abstractos de Datos (I) ........................... 27 Práctica 3: Tipos Abstractos de Datos (II) ........................... 29 Práctica 4: Tipos Abstractos de Datos (III) .......................... 31 Práctica 5: Gestión de Memoria Dinámica ........................... 34 Práctica 6: Abstracción en la Gestión de Memoria Dinámica (I) ............... 35 Práctica 7: Abstracción en la Gestión de Memoria Dinámica (II) .............. 36 Práctica 8: Introducción a la Programación Orientada a Objetos .............. 38 Práctica 9: La Clase Vector de la Biblioteca Estándar .................... 40 Prácticas de Autoevaluación 42 Gestión de Factoría de Androides ................................ 42 Gestión de Tareas Periódicas .................................. 46 cc Esta obra se encuentra bajo una licencia Reconocimiento-NoComercial-CompartirIgual 4.0 Internacional (CC BY-NC-SA 4.0) de Creative Commons. Véase http://creativecommons.org/licenses/by-nc-sa/4.0/deed.es_ES 1

Upload: others

Post on 10-Mar-2020

3 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Programación II

Relación de Ejercicios

Sonido e ImagenUNIVERSIDAD DE MÁLAGADpto. Lenguajes y CC. Computación

E.T.S.I. Telecomunicación

Contenido

Tema 1: Almacenamiento en Memoria Secundaria. Ficheros 2

Tema 2: Tipos Abstractos de Datos 3

Tema 2.1: Programacion Modular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3

Tema 2.2: Tipos Abstractos de Datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

Tema 3: Gestión de Memoria Dinámica 8

Tema 3.1: Listas Enlazadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Tema 3.2: Abstracción en la Gestión de Memoria Dinámica . . . . . . . . . . . . . . . . . 10

Tema 4: Introducción a la Programación Orientada a Objetos 16

Tema 5: Colecciones 24

Prácticas de Laboratorio 25

Práctica 1: Almacenamiento Persistente de Datos . . . . . . . . . . . . . . . . . . . . . . . 25

Práctica 2: Tipos Abstractos de Datos (I) . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

Práctica 3: Tipos Abstractos de Datos (II) . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

Práctica 4: Tipos Abstractos de Datos (III) . . . . . . . . . . . . . . . . . . . . . . . . . . 31

Práctica 5: Gestión de Memoria Dinámica . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

Práctica 6: Abstracción en la Gestión de Memoria Dinámica (I) . . . . . . . . . . . . . . . 35

Práctica 7: Abstracción en la Gestión de Memoria Dinámica (II) . . . . . . . . . . . . . . 36

Práctica 8: Introducción a la Programación Orientada a Objetos . . . . . . . . . . . . . . 38

Práctica 9: La Clase Vector de la Biblioteca Estándar . . . . . . . . . . . . . . . . . . . . 40

Prácticas de Autoevaluación 42

Gestión de Factoría de Androides . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

Gestión de Tareas Periódicas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

©cc Esta obra se encuentra bajo una licencia Reconocimiento-NoComercial-CompartirIgual 4.0 Internacional (CC BY-NC-SA 4.0) deCreative Commons. Véase http://creativecommons.org/licenses/by-nc-sa/4.0/deed.es_ES

1

Page 2: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Tema 1: Almacenamiento en Memoria Secundaria. Ficheros1. Escribir un programa que cuente el número de letras minúsculas, de letras mayúsculas y de dígitos de un

fichero.

2. Escribir un programa con la opción de encriptar y de desencriptar un fichero de texto, dependiendo de laextensión del fichero de entrada. La encriptación (codificación) consiste en que dado un fichero de textode entrada (extensión txt) genere otro fichero de salida encriptado (extensión cod). Esta codificaciónconsiste reemplazar cada letra por la tercera siguiente de forma circular (ej. a→d, b→e, · · ·, w→z, x→a,y→b, z→c). La opción de desencriptado consiste en leer un fichero codificado (extensión cod) y recuperarla información original en un fichero de texto (extensión txt).

3. Escribir un programa para procesar información sobre los clientes de una agencia matrimonial. El programadebe crear un fichero de texto (cuyo nombre se leerá por teclado) en el que se guarde la información deun número indeterminado de personas. La información que se guardará por cada persona será:Nombre: Cadena de caracteres.Edad int.Género char (M/F).Arte char (S/N).Deporte char (S/N).Libros char (S/N).Música char (S/N).

La información correspondiente a cada persona se leerá del teclado. El proceso finalizará cuando se tecleeun campo Nombre que esté vacío.

4. Ampliar el programa que procesa clientes de una agencia matrimonial para que tome los datos de todos loscandidatos a estudiar del fichero del ejercicio anterior, lea el cliente del teclado y finalmente genere comoresultado un fichero (cuyo nombre será leído desde teclado) con toda la información correspondiente a loscandidatos aceptados. Una persona del fichero de entrada se considerará aceptable como candidato si tienediferente género y por lo menos tres aficiones comunes con respecto al aspirante introducido por pantalla.(El programa debe ser capaz de trabajar con cualquier número de personas en el fichero de entrada).

5. Codifique un programa que cree un fichero para contener los datos relativos a los artículos de un almacén.Para cada artículo habrá de guardar la siguiente información:Código del artículo NuméricoNombre del artículo Cadena de caracteresExistencias NuméricoPrecio Numérico

Se deberá pedir datos de cada artículo por teclado hasta que se teclee 0 (cero) como código de artículo.

6. Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre loscampos existencias o precio. La condición podrá ser: <campo> [<,<=,>,>=, ==, ! =] <número>

Este programa debe generar como salida un fichero que contenga todos aquellos artículos para los que secumple la condición de entrada.

2

Page 3: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Tema 2: Tipos Abstractos de Datos

Tema 2.1: Programacion ModularDiseñe e implemente los siguientes Módulos, dentro del espacio de nombres umalcc, así como programas de

utilización que permitan comprobar su funcionamiento.

1. Diseñe un módulo que proporcione soporte adecuado a la arímetica con números complejos. El módulodeberá definir el tipo Complejo, así como los siguientes subprogramas:

void sumar(Complejo& r, const Complejo& a, const Complejo& b) ;// Devuelve un numero complejo ( r ) que cont iene e l r e su l t ado de// sumar l o s numeros complejos (a ) y ( b ) .

void restar(Complejo& r, const Complejo& a, const Complejo& b) ;// Devuelve un numero complejo ( r ) que cont iene e l r e su l t ado de// r e s t a r l o s numeros complejos (a ) y ( b ) .

void multiplicar(Complejo& r, const Complejo& a, const Complejo& b) ;// Devuelve un numero complejo ( r ) que cont iene e l r e su l t ado de// mu l t i p l i c a r l o s numeros complejos (a ) y ( b ) .

void dividir(Complejo& r, const Complejo& a, const Complejo& b) ;// Devuelve un numero complejo ( r ) que cont iene e l r e su l t ado de// d i v i d i r l o s numeros complejos (a ) y ( b ) .

bool iguales(const Complejo& a, const Complejo& b) ;// Devuelve t rue s i l o s numeros complejos (a ) y ( b ) son i g u a l e s .

void escribir(const Complejo& a) ;// Muestra en pan t a l l a e l numero complejo (a )

void leer(Complejo& a) ;// Lee de t e c l ado e l va l o r de l numero complejo (a ) .// Lee l a par te r e a l y l a par te imaginaria de l numero

2. Diseñe un módulo que proporcione soporte adecuado a la arímetica con números racionales. El módulodeberá definir el tipo Racional, así como los subprogramas adecuados teniendo en cuenta las siguientesconsideraciones:

Los números racionales se representan mediante fracciones, donde tanto el numerador como denomi-nador son de tipo int).Las fracciones se representarán en todo momento normalizadas (simplificadas):

• Es recomendable implementar un subprograma privado de simplificación de la fracción medianteel cálculo del máximo común divisor (m.c.d.) del numerador y el denominador y su posteriordivisión por dicho m.c.d.Para calcular el máximo común divisor de dos numeros enteros positivos n y m, el algoritmo deEuclides funciona como se indica a continuación:a) Si n < m, entonces se intercambian los valores de n y m (para asegurarnos que n siempre sea mayor

o igual que m).b) Si el valor de m es distinto de 0, entonces sea r el resto de la división entera entre n y m; después

modificamos los valores de n y m de la siguiente forma: n toma ahora el valor de m y m toma ahorael valor de r (el resto de la división entera entre n y m calculado anteriormente), y se repite esteproceso especificado hasta que el valor de m sea igual a 0.

c) Finalmente, cuando el proceso iterativo acaba, el valor de n es el máximo común divisor de ambosnúmeros.

• Para simplificar la determinación del signo de la fracción puede asumirse que el denominador dela fracción es siempre positivo (por lo que una fracción de signo negativo tendrá un numeradorde signo negativo y un denominador de signo positivo).

El número cero se guardará siempre en su forma canónica 0/1.Debe evitarse en todo momento la asignación de cero a un denominador.Debe proporcionar subprogramas para leer, escribir, sumar, restar, multiplicar y dividir fracciones.Pueden también suministrarse métodos para comparación de números racionales (iguales, menor,etc).

void sumar(Racional& r, const Racional& r1, const Racional& r2);// Asigna a l numero rac iona l ( r ) e l r e su l t ado de// sumar l o s numeros rac i ona l e s ( r1 ) y ( r2 )

void restar(Racional& r, const Racional& r1, const Racional& r2);

3

Page 4: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

// Asigna a l numero rac iona l ( r ) e l r e su l t ado de// r e s t a r l o s numeros rac i ona l e s ( r1 ) y ( r2 )

void multiplicar(Racional& r, const Racional& r1 , const Racional& r2);// Asigna a l numero rac iona l ( r ) e l r e su l t ado de// mu l t i p l i c a r l o s numeros rac i ona l e s ( r1 ) y ( r2 )

void dividir(Racional& r, const Racional& r1 , const Racional& r2);// Asigna a l numero rac iona l ( r ) e l r e su l t ado de// d i v i d i r l o s numeros rac i ona l e s ( r1 ) y ( r2 )

void escribir(const Racional& r);// Muestra en pan t a l l a e l va l o r de l numero rac iona l ( r )

void leer(Racional& r);// Lee de t e c l ado e l va l o r de l numero rac iona l ( r )

bool igual(const Racional& r1 , const Racional& r2);// Devuelve t rue s i e l numero rac iona l ( r1 ) es i g u a l a ( r2 )

bool menor(const Racional& r1 , const Racional& r2);// Devuelve t rue s i e l numero rac iona l ( r1 ) es menor que ( r2 )

3. Diseñe un módulo que proporcione soporte adecuado a la manipulación de polinomios de grados positivosmenores que 100. El módulo deberá definir el tipo Polinomio, así como las siguientes operaciones:

double evaluar(const Polinomio& a, double x);// Devuelve e l r e su l t ado de eva luar e l pol inomio (a )// para un va l o r de ( x ) e s p e c i f i c a do como parametro

void derivar(Polinomio& r, const Polinomio& a);// PRECOND: (&r != &a)// Devuelve un pol inomio ( r ) que cont iene e l r e su l t ado de// ca l c u l a r l a der ivada de l pol inomio (a )

void sumar(Polinomio& r, const Polinomio& a, const Polinomio& b);// PRECOND: ((&r != &a)&&(&r != &b ))// Devuelve un pol inomio ( r ) que cont iene e l r e su l t ado de// sumar l o s pol inomios (a ) y ( b )

void escribir(const Polinomio& a) ;// Muestra en pan t a l l a e l contenido de l pol inomio (a )

void leer(Polinomio& a) ;// Lee de t e c l ado e l va l o r de l pol inomio (a )// Lee pares de c o e f i c i e n t e y grado hasta que e l c o e f i c i e n t e sea cero

Tema 2.2: Tipos Abstractos de DatosDiseñe e implemente los siguientes TADs, dentro del espacio de nombres umalcc, así como programas de

utilización que permitan comprobar su funcionamiento.

1. TAD número complejo que defina los siguientes métodos públicos:

class Complejo {public:

Complejo () ;// Constructor por Defecto

Complejo(double parte_real , double parte_imag) ;// Constructor e s p e c i f i c o

double parte_real () const ;// Devuelve l a par te r e a l d e l numero complejo

double parte_imag () const ;// Devuelve l a par te imaginaria de l numero complejo

void sumar(const Complejo& a, const Complejo& b) ;// Asigna a l numero complejo ( ac tua l ) e l r e su l t ado de// sumar l o s numeros complejos (a ) y ( b ) .

void restar(const Complejo& a, const Complejo& b) ;// Asigna a l numero complejo ( ac tua l ) e l r e su l t ado de// r e s t a r l o s numeros complejos (a ) y ( b ) .

void multiplicar(const Complejo& a, const Complejo& b) ;// Asigna a l numero complejo ( ac tua l ) e l r e su l t ado de// mu l t i p l i c a r l o s numeros complejos (a ) y ( b ) .

void dividir(const Complejo& a, const Complejo& b) ;// Asigna a l numero complejo ( ac tua l ) e l r e su l t ado de// d i v i d i r l o s numeros complejos (a ) y ( b ) .

bool igual(const Complejo& b) const ;// Devuelve t rue s i e l numero complejo ( ac tua l ) es// i g u a l a l numero complejo ( b )

void escribir () const ;// Muestra en pan t a l l a e l numero complejo ( ac tua l )

4

Page 5: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

void leer() ;// Lee de t e c l ado e l va l o r de l numero complejo ( ac tua l ) .// Lee l a par te r e a l y l a par te imaginaria de l numero

} ;

2. TAD polinomio de grados positivos menores que 100 que defina los siguientes métodos públicos:

class Polinomio {public:

˜ Polinomio ();// Destructor

Polinomio ();// Constructor por Defecto

Polinomio(const Polinomio& p);// Constructor de copia

Polinomio& operator=(const Polinomio& p);// Operador de Asignacion

int max_grado () const;// Devuelve e l mayor grado de l pol inomio ac tua l// cuyo c o e f i c i e n t e es d i s t i n t o de cero

void poner(int e, double c);// Asigna e l c o e f i c i e n t e ( c ) a l termino de grado ( e )// de l pol inomio ac tua l

double obtener(int e) const;// Devuelve e l c o e f i c i e n t e correspond ien te a l// termino de grado ( e ) de l pol inomio ac tua l

double evaluar(double x) const;// Devuelve e l r e su l t ado de eva luar e l pol inomio ac tua l// para un va l o r de ( x ) e s p e c i f i c a do como parametro

void derivar(const Polinomio& a);// PRECOND: ( t h i s != &a)// Asigna a l pol inomio ac tua l e l r e su l t ado de// ca l c u l a r l a der ivada de l pol inomio (a )

void sumar(const Polinomio& a, const Polinomio& b);// PRECOND: (( t h i s != &a)&&( t h i s != &b ))// Asigna a l pol inomio ac tua l e l r e su l t ado de// sumar l o s pol inomios (a ) y ( b )

void escribir () const;// Muestra en pan t a l l a e l contenido de l pol inomio ac tua l

void leer ();// Lee de t e c l ado e l va l o r de l pol inomio ac tua l// Lee pares de c o e f i c i e n t e y grado hasta que e l c o e f i c i e n t e sea cero

};

3. Un conjunto de números enteros es una colección de elementos homogéneos (números enteros) sin repeticióny ninguna relación de orden entre ellos (no ordenados y sin repetición). Defina un TAD Conjunto denúmeros enteros que defina los siguientes métodos públicos:

class Conjunto {public:

˜ Conjunto ();// Destructor

Conjunto ();// Constructor por Defecto : conjunto vac io

Conjunto(const Conjunto& c);// Constructor de copia

Conjunto& operator=(const Conjunto& c);// Operador de Asignacion

void clear ();// Elimina todos l o s e lementos de l conjunto ac tua l ( queda vac io )

bool es_vacio () const;// Devuelve t rue s i e l conjunto ac tua l e s ta vac io

void incluir(int e);// Inc luye e l elemento ( e ) en e l conjunto ac tua l ( s in r e p e t i c i on )

void eliminar(int e);// Elimina e l elemento ( e ) de l conjunto ac tua l

bool pertenece(int e) const;// Devuelve t rue s i e l e lemento ( e ) per tenece a l conjunto ac tua l

bool es_subconjunto(const Conjunto& a) const;// Devuelve t rue s i e l conjunto ac tua l es subconjunto de l conjunto (a )

void union_conj(const Conjunto& a, const Conjunto& b);// PRECOND: (( t h i s != &a)&&( t h i s != &b ))

5

Page 6: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

// Asigna a l conjunto ac tua l e l r e su l t ado de// l a union de l o s conjuntos (a ) y ( b )

void interseccion(const Conjunto& a, const Conjunto& b);// PRECOND: (( t h i s != &a)&&( t h i s != &b ))// Asigna a l conjunto ac tua l e l r e su l t ado de// l a i n t e r s e c c i on de l o s conjuntos (a ) y ( b )

void diferencia(const Conjunto& a, const Conjunto& b);// PRECOND: (( t h i s != &a)&&( t h i s != &b ))// Asigna a l conjunto ac tua l e l r e su l t ado de// l a d i f e r en c i a de l o s conjuntos (a ) y ( b )

void diferencia_simetrica(const Conjunto& a, const Conjunto& b);// Asigna a l conjunto ac tua l e l r e su l t ado de// l a d i f e r en c i a s ime t r i ca de l o s conjuntos (a ) y ( b )

void escribir () const;// Muestra en pan t a l l a e l contenido de l conjunto ac tua l

void leer ();// Lee de t e c l ado e l va l o r de l conjunto actua l ,

};

4. TAD matriz matemática de números reales (de dimensiones menores de N ×N) que defina los siguientesmétodos públicos:

class Matriz {public:

˜ Matriz ();// Destructor

Matriz ();// Constructor por Defecto : matriz vac ia

Matriz(int nfils , int ncols );// Constructor e s p e c i f i c o : crea matriz de ( n f i l s ) x ( nco l s ) con va l o r e s 0

Matriz(const Matriz& m);// Constructor de copia

Matriz& operator=(const Matriz& m);// Operador de Asignacion

void clear(int nfils , int ncols);// Elimina todos l o s e lementos de l a matriz ac tua l , y as igna// a l a matriz a c tua l una matriz de ( n f i l s ) x ( nco l s ) con va l o r e s 0

int nfils () const;// Devuelve e l numero de f i l a s de l a matriz a c tua l

int ncols () const;// Devuelve e l numero de columnas de l a matriz ac tua l

void poner(int f, int c, double val);// PRECOND: (0 <= f && f < n f i l s ( ) && 0 <= c && c < nco l s ( ) )// Asigna e l va l o r ( va l ) a l elemento de l a f i l a ( f )// y columna ( c ) de l a matriz a c tua l

double obtener(int f, int c) const;// PRECOND: ( f < n f i l s ( ) && c < nco l s ( ) )// Devuelve e l va l o r de l elemento de l a f i l a ( f )// y columna ( c ) de l a matriz a c tua l

void sumar(const Matriz& a, const Matriz& b);// PRECOND: (( t h i s != &a)&&( t h i s != &b ))// Asigna a l a matriz a c tua l e l r e su l t ado de// sumar l a s matr ices (a ) y ( b )

void restar(const Matriz& a, const Matriz& b);// PRECOND: (( t h i s != &a)&&( t h i s != &b ))// Asigna a l a matriz a c tua l e l r e su l t ado de// r e s t a r l a s matr ices (a ) y ( b )

void multiplicar(const Matriz& a, const Matriz& b);// PRECOND: (( t h i s != &a)&&( t h i s != &b ))// Asigna a l a matriz a c tua l e l r e su l t ado de// mu l t i p l i c a r l a s matr ices (a ) y ( b )

void escribir () const;// Muestra en pan t a l l a e l contenido de l a matriz a c tua l

void leer ();// Lee de t e c l ado e l va l o r de l a matriz ac tua l ,// Lee n f i l s , nco l s y l o s va l o r e s de l o s e lementos

};

5. Un TAD Lista de números enteros es una secuencia de elementos homogéneos (números enteros), dondecada elemento ocupa una determinada posición dentro de la secuencia, de tal forma que se puede accedera cada elemento por la posición donde se encuentra. Así mismo, también es posible insertar y eliminar

6

Page 7: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

elementos de la secuencia en la posición indicada, manteniendo el mismo orden posicional de los elementosen la secuencia. Diseñe e implemente el TAD que proporcione los siguientes métodos públicos:

class ListaInt {public:

˜ ListaInt () ;// Destructor

ListaInt () ;// Constructor por Defecto

ListaInt(const ListaInt& o) ;// Constructor de copia

ListaInt& operator = (const ListaInt& o) ;// Operador de Asignacion

bool llena() const ;// Devuelve t rue s i e l numero de elementos almacenados// a lcanza l a capacidad maxima de almacenamiento

int size() const ;// Devuelve e l numero de elementos almacenados

void clear() ;// Elimina todos l o s e lementos de l a l i s t a ac tua l ( queda vac ia )

void insertar(int pos , int dato) ;// PRECOND: ( ! l l e n a () && 0 <= pos && pos <= s i z e ( ) )// Inse r ta ( dato ) en l a l i s t a ac tua l en l a pos i c ion ( pos )

void eliminar(int pos) ;// PRECOND: (0 <= pos && pos < s i z e ( ) )// Elimina de l a l i s t a ac tua l e l e lemento que ocupa l a pos i c ion ( pos )

int acceder(int pos) const ;// PRECOND: (0 <= pos && pos < s i z e ( ) )// Devuelve e l elemento de l a l i s t a ac tua l que ocupa l a pos i c ion ( pos )

void modificar(int pos , int dato);// PRECOND: (0 <= pos && pos < s i z e ( ) )// Asigna ( dato ) a l elemento de l a l i s t a ac tua l que ocupa l a pos i c ion ( pos )

} ;

7

Page 8: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Tema 3: Gestión de Memoria Dinámica

Tema 3.1: Listas Enlazadas1. Diseñe un módulo (programación modular) que proporcione soporte adecuado a la manipulación de listas

enlazadas en memoria dinámica (véase siguiente figura). El módulo deberá definir el tipo PNodo como unpuntero a un registro en memoria dinámica de tipo Nodo que contiene un enlace al siguiente nodo, asícomo un dato de tipo int. Además, el módulo deberá definir los siguientes subprogramas. Diseñe tambiénun módulo principal que permita comprobar la corrección del módulo lista implementado.

lista: −−→◦ −−−−→◦0

−−−−→◦1

�2

void inicializa(PNodo& lista) ;// I n i c i a l i z a ( l i s t a ) a una l i s t a vac ia

void destruir(PNodo& lista) ;// Destruye todos l o s e lementos de l a l i s t a , l i b e rando// todos l o s nodos de memoria dinamica . ( l i s t a ) queda vac ia

void escribir(PNodo lista) ;// Muestra en pan t a l l a e l contenido de ( l i s t a )

PNodo buscar(PNodo lista , int dt) ;// Devuelve un puntero a l nodo que cont iene e l elemento// i g u a l a ( dt ) . Si no se encuentra , entonces devue l ve NULL

void insertar_principio(PNodo& lista , int dt) ;// Inse r ta un elemento a l p r i n c i p i o de ( l i s t a )

void insertar_final(PNodo& lista , int dt) ;// Inse r ta un elemento a l f i n a l de ( l i s t a )

void insertar_ord(PNodo& lista , int dt) ;// Inse r ta un elemento de forma ordenada en ( l i s t a ) , que debe e s t a r ordenada

void eliminar_primero(PNodo& lista) ;// Elimina e l primer elemento de ( l i s t a ) , s i e x i s t e

void eliminar_ultimo(PNodo& lista) ;// Elimina e l u l t imo elemento de ( l i s t a ) , s i e x i s t e

void eliminar_elem(PNodo& lista , int dt) ;// Elimina de ( l i s t a ) e l primer elemento i g u a l a ( dt ) , s i e x i s t e

PNodo situar(PNodo lista , int pos) ;// Devuelve un puntero a l nodo que se encuentra en l a pos i c ion// indicada por ( pos ) . La pos i c ion cero (0) ind i ca e l primer nodo .// Si e l nodo no ex i s t e , entonces devue l ve NULL

void insertar(PNodo& lista , int pos , int dt) ;// Inse r ta en ( l i s t a ) un elemento en l a pos i c ion indicada por ( pos )

void eliminar(PNodo& lista , int pos) ;// Elimina de ( l i s t a ) e l e lemento de l a pos i c ion indicada por ( pos ) , s i e x i s t e

PNodo duplicar(PNodo lista) ;// Devuelve un puntero a una nueva l i s t a r e su l t ado de dup l i c a r en// memoria dinamica l a l i s t a r e c i b i d a como parametro

PNodo leer() ;// Devuelve una l i s t a con l o s numeros l e i d o s de t e c l ado ( en e l mismo// orden que son in t roduc ido s ) hasta que l e a e l numero 0 ( que no es// in t roduc ido )

void eliminar_mayor(PNodo& lista) ;// Elimina e l mayor elemento de ( l i s t a ) , s i e x i s t e

void purgar(PNodo& lista , int dt) ;// Elimina de ( l i s t a ) todos l o s e lementos que sean i g u a l e s a ( dt ) , s i e x i s t e n

2. Un conjunto de números enteros es una colección de elementos homogéneos (números enteros) sin repeticióny ninguna relación de orden entre ellos (no ordenados y sin repetición).

Un conjunto de elementos se puede representar mediante una lista enlazada, donde cada nodo contieneun elemento del conjunto. Por ejemplo el conjunto con los elementos {1, 2, 3} puede ser representado porla siguiente lista enlazada:

lista: −−→◦ −−−−→◦1

−−−−→◦2

�3

8

Page 9: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Diseñe un módulo (programación modular) que proporcione soporte adecuado a la manipulación de con-juntos de números enteros implementados mediante listas enlazadas en memoria dinámica (véase figuraanterior). El módulo deberá definir el tipo Conjunto como un registro con un campo de tipo PNodo, que sedefine como un tipo puntero a un registro en memoria dinámica de tipo Nodo que contiene un enlace al si-guiente nodo, así como un dato de tipo int. Además, el módulo deberá definir los siguientes subprogramas.Diseñe también un módulo principal que permita comprobar la corrección del módulo implementado.

void inicializar(Conjunto& c);// I n i c i a l i z a ( c ) a un conjunto vac io

void destruir(Conjunto& c);// Destruye todos l o s e lementos de l conjunto , l i b e rando// todos l o s nodos de memoria dinamica . ( c ) queda vac io

bool es_vacio(const Conjunto& c) ;// Devuelve t rue s i e l conjunto ( c ) e s ta vac io

void incluir(Conjunto& c, int e);// Inc luye e l elemento ( e ) en e l conjunto ( c ) ( s in r e p e t i c i on )

void eliminar(Conjunto& c, int e);// Elimina e l elemento ( e ) de l conjunto ( c )

bool pertenece(const Conjunto& c, int e) ;// Devuelve t rue s i e l e lemento ( e ) per tenece a l conjunto ( c )

void escribir(const Conjunto& c) ;// Muestra en pan t a l l a e l contenido de l conjunto ( c )

void leer(Conjunto& c);// Lee de t e c l ado e l va l o r de l conjunto ( c )

bool es_subconjunto(const Conjunto& a, const Conjunto& b) ;// Devuelve t rue s i e l conjunto (a ) es subconjunto de l conjunto ( b )

void union_conj(Conjunto& c, const Conjunto& a, const Conjunto& b);// Asigna a l conjunto ( c ) e l r e su l t ado de// l a union de l o s conjuntos (a ) y ( b ) ( dup l i ca l o s nodos )

void interseccion(Conjunto& c, const Conjunto& a, const Conjunto& b);// Asigna a l conjunto ( c ) e l r e su l t ado de// l a i n t e r s e c c i on de l o s conjuntos (a ) y ( b ) ( dup l i ca l o s nodos )

void diferencia(Conjunto& c, const Conjunto& a, const Conjunto& b);// Asigna a l conjunto ( c ) e l r e su l t ado de// l a d i f e r en c i a de l o s conjuntos (a ) y ( b ) ( dup l i ca l o s nodos )

void diferencia_simetrica(Conjunto& c, const Conjunto& a, const Conjunto& b);// Asigna a l conjunto ( c ) e l r e su l t ado de// l a d i f e r en c i a s ime t r i ca de l o s conjuntos (a ) y ( b ) ( dup l i ca l o s nodos )

void copiar(Conjunto& d, const Conjunto& o) ;// Copia ( dup l i ca ) e l conjunto (o ) en e l conjunto (d )

Nota: aunque el orden en el que se encuentran los elementos en el conjunto no es importante, y por lotanto, la opción más simple para incluir elementos en él podría ser “insertar siempre los elementos por elprincipio”, con objeto de prácticar los conceptos de listas enlazadas, en esta práctica, los elementos delconjunto serán insertados (sin repetición) ordenados en la lista enlazada donde se encuentran almacenados.

3. Diseñe un módulo (programación modular) que proporcione soporte adecuado a la manipulación de listasdoblemente enlazadas en memoria dinámica (véase siguiente figura). El módulo deberá definir el tipoPNodo como un puntero a un registro en memoria dinámica de tipo Nodo que contiene un enlace al siguientenodo, un enlace al nodo anterior, así como un dato de tipo int. Además, el módulo deberá definir lossiguientes subprogramas. Diseñe también un módulo principal que permita comprobar la corrección delmódulo lista implementado.

lista: −−→◦ −−−−−→◦�0

−−−−−→◦←−−−−−◦

1

�←−−−−−◦

2

void inicializa(PNodo& lista) ;// I n i c i a l i z a ( l i s t a ) a una l i s t a vac ia

void destruir(PNodo& lista) ;// Destruye todos l o s e lementos de l a l i s t a , l i b e rando// todos l o s nodos de memoria dinamica . ( l i s t a ) queda vac ia

void escribir(PNodo lista) ;// Muestra en pan t a l l a e l contenido de ( l i s t a )

PNodo buscar(PNodo lista , int dt) ;// Devuelve un puntero a l nodo que cont iene e l elemento// i g u a l a ( dt ) . Si no se encuentra , entonces devue l ve NULL

9

Page 10: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

void insertar_principio(PNodo& lista , int dt) ;// Inse r ta un elemento a l p r i n c i p i o de ( l i s t a )

void insertar_final(PNodo& lista , int dt) ;// Inse r ta un elemento a l f i n a l de ( l i s t a )

void insertar_ord(PNodo& lista , int dt) ;// Inse r ta un elemento de forma ordenada en ( l i s t a ) , que debe e s t a r ordenada

void eliminar_primero(PNodo& lista) ;// Elimina e l primer elemento de ( l i s t a ) , s i e x i s t e

void eliminar_ultimo(PNodo& lista) ;// Elimina e l u l t imo elemento de ( l i s t a ) , s i e x i s t e

void eliminar_elem(PNodo& lista , int dt) ;// Elimina de ( l i s t a ) e l primer elemento i g u a l a ( dt ) , s i e x i s t e

PNodo situar(PNodo lista , int pos) ;// Devuelve un puntero a l nodo que se encuentra en l a pos i c ion// indicada por ( pos ) . La pos i c ion cero (0) ind i ca e l primer nodo .// Si e l nodo no ex i s t e , entonces devue l ve NULL

void insertar(PNodo& lista , int pos , int dt) ;// Inse r ta en ( l i s t a ) un elemento en l a pos i c ion indicada por ( pos )

void eliminar(PNodo& lista , int pos) ;// Elimina de ( l i s t a ) e l e lemento de l a pos i c ion indicada por ( pos ) , s i e x i s t e

PNodo duplicar(PNodo lista) ;// Devuelve un puntero a una nueva l i s t a r e su l t ado de dup l i c a r en// memoria dinamica l a l i s t a r e c i b i d a como parametro

PNodo leer() ;// Devuelve una l i s t a con l o s numeros l e i d o s de t e c l ado ( en e l mismo// orden que son in t roduc ido s ) hasta que l e a e l numero 0 ( que no es// in t roduc ido )

void eliminar_mayor(PNodo& lista) ;// Elimina e l mayor elemento de ( l i s t a ) , s i e x i s t e

void purgar(PNodo& lista , int dt) ;// Elimina de ( l i s t a ) todos l o s e lementos que sean i g u a l e s a ( dt ) , s i e x i s t e n

Tema 3.2: Abstracción en la Gestión de Memoria Dinámica1. Un polinomio en x de grado arbitrario se puede representar mediante una lista enlazada, donde cada nodo

contiene el coeficiente y el exponente de un término del polinomio, y donde los coeficientes con valor cero(0) no serán almacenados. Por ejemplo el polinomio 25x − 14x5 puede ser representado por la siguientelista enlazada:

lista: −−→◦ −−−−→◦251

�-145

Diseñe e implemente el TAD polinomio que defina los siguientes métodos públicos, así como un programapara comprobar su funcionamiento:

class Polinomio {public:

˜ Polinomio ();// Destructor

Polinomio ();// Constructor por Defecto

Polinomio(const Polinomio& p);// Constructor de copia

Polinomio& operator=(const Polinomio& p);// Operador de Asignacion

int max_grado () const;// Devuelve e l mayor grado de l pol inomio ac tua l// cuyo c o e f i c i e n t e es d i s t i n t o de cero

void poner(int e, double c);// Asigna e l c o e f i c i e n t e ( c ) a l termino de grado ( e )// de l pol inomio ac tua l

double obtener(int e) const;// Devuelve e l c o e f i c i e n t e correspond ien te a l// termino de grado ( e ) de l pol inomio ac tua l

double evaluar(double x) const;// Devuelve e l r e su l t ado de eva luar e l pol inomio ac tua l// para un va l o r de ( x ) e s p e c i f i c a do como parametro

void derivar(const Polinomio& a);

10

Page 11: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

// Asigna a l pol inomio ac tua l e l r e su l t ado de// c a l c u l a r l a der ivada de l pol inomio (a )

void sumar(const Polinomio& a, const Polinomio& b);// Asigna a l pol inomio ac tua l e l r e su l t ado de// sumar l o s pol inomios (a ) y ( b )

void escribir () const;// Muestra en pan t a l l a e l contenido de l pol inomio ac tua l

void leer ();// Lee de t e c l ado e l va l o r de l pol inomio ac tua l// Lee pares de c o e f i c i e n t e y grado hasta que e l c o e f i c i e n t e sea cero

};

2. Un conjunto de números enteros es una colección de elementos homogéneos (números enteros) sin repeticióny ninguna relación de orden entre ellos (no ordenados y sin repetición).Un conjunto de elementos se puede representar mediante una lista enlazada, donde cada nodo contieneun elemento del conjunto. Por ejemplo el conjunto con los elementos {1, 2, 3} puede ser representado porla siguiente lista enlazada:

lista: −−→◦ −−−−→◦1

−−−−→◦2

�3

Diseñe e implemente el siguiente TAD conjunto de números enteros que defina los siguientes métodospúblicos, así como un programa para comprobar su funcionamiento:

class Conjunto {public:

˜ Conjunto ();// Destructor

Conjunto ();// Constructor por Defecto : conjunto vac io

Conjunto(const Conjunto& c);// Constructor de copia

Conjunto& operator=(const Conjunto& c);// Operador de Asignacion

void clear ();// Elimina todos l o s e lementos de l conjunto ac tua l ( queda vac io )

bool es_vacio () const;// Devuelve t rue s i e l conjunto ac tua l e s ta vac io

void incluir(int e);// Inc luye e l elemento ( e ) en e l conjunto ac tua l ( s in r e p e t i c i on )

void eliminar(int e);// Elimina e l elemento ( e ) de l conjunto ac tua l

bool pertenece(int e) const;// Devuelve t rue s i e l e lemento ( e ) per tenece a l conjunto ac tua l

bool es_subconjunto(const Conjunto& a) const;// Devuelve t rue s i e l conjunto ac tua l es subconjunto de l conjunto (a )

void union_conj(const Conjunto& a, const Conjunto& b);// Asigna a l conjunto ac tua l e l r e su l t ado de// l a union de l o s conjuntos (a ) y ( b )

void interseccion(const Conjunto& a, const Conjunto& b);// Asigna a l conjunto ac tua l e l r e su l t ado de// l a i n t e r s e c c i on de l o s conjuntos (a ) y ( b )

void diferencia(const Conjunto& a, const Conjunto& b);// Asigna a l conjunto ac tua l e l r e su l t ado de// l a d i f e r en c i a de l o s conjuntos (a ) y ( b )

void diferencia_simetrica(const Conjunto& a, const Conjunto& b);// Asigna a l conjunto ac tua l e l r e su l t ado de// l a d i f e r en c i a s ime t r i ca de l o s conjuntos (a ) y ( b )

void escribir () const;// Muestra en pan t a l l a e l contenido de l conjunto ac tua l

void leer ();// Lee de t e c l ado e l va l o r de l conjunto actua l ,

};

3. Hay muchas aplicaciones en las que se deben almacenar en la memoria matrices de grandes dimensiones. Sila mayoría de los elementos de la matriz son ceros, ésta, en lugar de almacenarse en un array bidimensional,se puede representar más eficientemente utilizando listas enlazadas donde los elementos nulos y filas nulasno serán almacenadas.

11

Page 12: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Así, defina la clase MatrizDispersa en el espacio de nombres umalcc_aux que represente dicha abstraccióny proporcione las siguientes operaciones:

class MatrizDispersa {public:

˜ MatrizDispersa ();// Destructor

MatrizDispersa ();// Constructor por Defecto : matriz vac ia

MatrizDispersa(int nfils , int ncols );// Constructor e s p e c i f i c o : crea matriz de ( n f i l s ) x ( nco l s ) con va l o r e s 0

MatrizDispersa(const MatrizDispersa& m);// Constructor de copia

MatrizDispersa& operator=(const MatrizDispersa& m);// Operador de Asignacion

void clear(int nfils , int ncols);// Elimina todos l o s e lementos de l a matriz ac tua l , y as igna// a l a matriz a c tua l una matriz de ( n f i l s ) x ( nco l s ) con va l o r e s 0

int nfils () const;// Devuelve e l numero de f i l a s de l a matriz a c tua l

int ncols () const;// Devuelve e l numero de columnas de l a matriz ac tua l

void poner(int f, int c, double val);// PRECOND: (0 <= f && f < n f i l s ( ) && 0 <= c && c < nco l s ( ) )// Asigna e l va l o r ( va l ) a l elemento de l a f i l a ( f )// y columna ( c ) de l a matriz a c tua l

double obtener(int f, int c) const;// PRECOND: ( f < n f i l s ( ) && c < nco l s ( ) )// Devuelve e l va l o r de l elemento de l a f i l a ( f )// y columna ( c ) de l a matriz a c tua l

};

Utilice la siguiente estructura para implementar la matriz dispersa, donde hay una lista enlazada ordenada(ascendentemente por número de fila) para acceder por filas, y a partir de un determinado nodo fila, sepuede acceder a la lista enlazada ordenada (ascendentemente por número de columna) donde se encuentranlos elementos pertenecientes a dicha fila y a la columna especificada en el nodo cuyo valor es distinto decero. Por ejemplo, la siguiente figura representa la siguiente matriz:

0

2

3

0 40 1 60 3 90

0 50 2 75

1 67 2 83

4

4

nfil

ncol

filas

40 60 0 900 0 0 050 0 75 00 67 83 0

con las siguientes especificaciones adicionales:

El método obtener permite conocer el valor de un determinado elemento de la matriz especificadopor su fila y columna correspondiente. En caso de que dicho elemento no esté almacenado, entoncessu valor es cero.

El método poner permite asignar un determinado valor a un determinado elemento de la matrizespecificado por su fila y columna correspondiente.Solo se almacenarán los elementos de valor distinto de cero, considerando que si un elemento noestá almacenado, es que su valor es cero. Si una fila no tiene elementos distintos de cero, el nodocorrespondiente a dicha fila no será almacenado.Si el valor a almacenar es distinto de cero, si el elemento ya existe, se reemplazará su valor, en otrocaso se añadirá a la estructura.

12

Page 13: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Si el valor a almacenar es cero, habrá que eliminar dicho elemento de la estructura si es que existe.Si como consecuencia de ello, la fila queda sin elementos, habrá que eliminar el nodo correspondientede dicha lista.

4. Se debe diseñar e implementar el tipo abstracto de datos Matriz de números reales en el espacio de nombreumalcc, junto con las operaciones necesarias para su gestión y tratamiento. Utilice para su implementaciónla clase MatrizDispersa realizada en el ejercicio anterior.

class Matriz {public:

˜ Matriz ();// Destructor

Matriz ();// Constructor por Defecto : matriz vac ia

Matriz(int nfils , int ncols );// Constructor e s p e c i f i c o : crea matriz de ( n f i l s ) x ( nco l s ) con va l o r e s 0

Matriz(const Matriz& m);// Constructor de copia

Matriz& operator=(const Matriz& m);// Operador de Asignacion

void clear(int nfils , int ncols);// Elimina todos l o s e lementos de l a matriz ac tua l , y as igna// a l a matriz a c tua l una matriz de ( n f i l s ) x ( nco l s ) con va l o r e s 0

int nfils () const;// Devuelve e l numero de f i l a s de l a matriz a c tua l

int ncols () const;// Devuelve e l numero de columnas de l a matriz ac tua l

void poner(int f, int c, double val);// PRECOND: (0 <= f && f < n f i l s ( ) && 0 <= c && c < nco l s ( ) )// Asigna e l va l o r ( va l ) a l elemento de l a f i l a ( f )// y columna ( c ) de l a matriz a c tua l

double obtener(int f, int c) const;// PRECOND: ( f < n f i l s ( ) && c < nco l s ( ) )// Devuelve e l va l o r de l elemento de l a f i l a ( f )// y columna ( c ) de l a matriz a c tua l

void sumar(const Matriz& a, const Matriz& b);// PRECOND: (( t h i s != &a)&&( t h i s != &b ) ) ;// Asigna a l a matriz a c tua l e l r e su l t ado de// sumar l a s matr ices (a ) y ( b )

void restar(const Matriz& a, const Matriz& b);// PRECOND: (( t h i s != &a)&&( t h i s != &b ) ) ;// Asigna a l a matriz a c tua l e l r e su l t ado de// r e s t a r l a s matr ices (a ) y ( b )

void multiplicar(const Matriz& a, const Matriz& b);// PRECOND: (( t h i s != &a)&&( t h i s != &b ) ) ;// Asigna a l a matriz a c tua l e l r e su l t ado de// mu l t i p l i c a r l a s matr ices (a ) y ( b )

void escribir () const;// Muestra en pan t a l l a e l contenido de l a matriz a c tua l

void leer ();// Lee de t e c l ado e l va l o r de l a matriz ac tua l ,// Lee n f i l s , nco l s y l o s va l o r e s de l o s e lementos

};

5. Implemente un programa principal que permita comprobar el funcionamiento del tipo abstracto de datosMatriz definido previamente.

6. Se dispone de un procesador con varias etapas, y de unas determinadas tareas que se ejecutarán pasandosucesivamente por todas las etapas del procesador, desde la primera hasta la última. Como el procesadordispone de varias etapas, es posible que esté procesando simultáneamente diferentes tareas. Por tanto,una tarea sólo podrá pasar a la siguiente etapa si ésta se encuentra libre. La siguiente figura muestra unprocesador con cuatro etapas y dos tareas, la tarea T1 va ejecutándose por la etapa e2 y la tarea T2 vaejecutándose por la etapa e4.

procesador

e1 e3 e4e2

t1 t2

Se debe diseñar la estructura de datos necesaria para representar la información del estado del procesadoren cada momento. Para ello, se sigue el esquema mostrado en la siguiente figura. Como se puede observar

13

Page 14: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

cada etapa se representa con dos elementos, una lista de nodos intermedios con tantos nodos como réplicas(véase más adelante) haya de la etapa (en el ejemplo sólo se muestra una réplica por cada etapa) y loscorrespondientes nodos de etapa. Cada nodo de etapa contendrá su identificador, el número de la tareaque está ejecutando (un número cero indica que está libre, es decir, no está ejecutando ninguna tarea),y un puntero al primer nodo de la lista de nodos intermedios de la siguiente etapa. También se puedeobservar que la tarea T1 se está ejecutando en la etapa 2 y la tarea T2 se está ejecutando en la etapa 4.

0

1

1

2

0

3

2

4procesador

Es posible que en un determinado momento interese ampliar la potencia de una determinada etapa. Paraello, se replicará dicha etapa haciendo tantos duplicados de la misma como se desee. Así mismo, es posibleque interese reducir la potencia de una determinada etapa, para ello se eliminarán réplicas de la misma.

Defina el TAD Procesador que implemente la estructura de datos especificada anteriormente, y que propor-cione los siguientes métodos públicos, así mismo, también se deberá implementar un programa principalque permita su utilización:

a) ElConstructor recibe el número de etapas que tiene un determinado procesador, y crea la estructurabase de étapas sin replicación y todas en estado inicial libre, como se muestra en la siguiente figurapara un procesador de 4 etapas:

0

1

0

2

0

3

0

4procesador

b) El Destructor libera todos los recursos asociados al objeto que está siendo destruido.

c) El método Mostrar muestra en pantalla la estructura interna de un procesador. Por ejemplo, parala figura anterior:

Etapa: 1Replica: libreReplica: libre

Etapa: 2Replica: tarea 1Replica: tarea 2

Etapa: 3Replica: libre

Etapa: 4Replica: libre

d) Un métodoReplicar, que se usará para ampliar la potencia de una determinada etapa del procesadoractual. Recibe como parámetros el identificador de la etapa a replicar y el número de réplicas quedeseamos añadir. Las réplicas añadidas tendrán el estado inicial libre (no tienen asignadas la ejecuciónde ninguna tarea).Las réplicas se añadirán a la estructura añadiendo (en cualquier posición SALVO AL PRINCIPIO)nodos a la lista de nodos intermedios correspondiente a la etapa y nodos de etapa apuntados desde losnodos intermedios añadidos. Como se puede observar, todas las réplicas añadidas deben apuntar alprimer nodo intermedio de la etapa siguiente (salvo en la última etapa). La siguiente figura muestrael resultado de añadir dos réplicas de la etapa 2 a la figura anterior:

0

1

1

2

0

3

2

4

0

2

0

2

procesador

La siguiente figura muestra el resultado de añadir una réplica de la etapa 1 a la figura anterior:

14

Page 15: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

0

1

1

2

0

3

2

4

0

2

0

2

0

1

procesador

e) Un método para Compactar que se usará para disminuir el número de réplicas de una etapa delprocesador actual. Para ello, recibe como parámetro el identificador de la etapa a compactar yelimina todas las réplicas de dicha etapa cuyo estado sea libre (no esté ejecutando ninguna tarea).Al compactar etapas habrá que tener en cuenta que:

De cada etapa deberá quedar al menos una réplica.Las réplicas que estén ejecutando alguna tarea no pueden ser eliminadas.No se podrá liberar la memoria ocupada por el primer nodo de la lista de nodos intermedios deuna etapa (pues sirve de enlace entre una etapa y la siguiente). En caso de que la compactaciónrequiera eliminar la primera réplica de una etapa (porque esté libre), el puntero al nodo deetapa del primer nodo de la lista de nodos intermedios pasará a apuntar a un nodo de etapa quepermanezca tras la compactación. Por ejemplo, para la siguiente figura:

0

1

0

2

0

3

0

4

2

2

1

2

0

1

procesador

la siguiente figura es el resultado de compactar la etapa 2 de la figura anterior:

0

1

0

3

0

4

2

2

1

2

0

1

procesador

f ) El método AvanzarEvaluacion intenta avanzar una tarea de una determinada etapa a la siguiente.Para ello, recibe como parámetro el número de tarea (distinto de cero) que pretende avanzar a lasiguiente etapa.

Si la tarea es nueva, buscará una réplica libre de la primera etapa del procesador. Si no hayréplicas libres en esta primera etapa, entonces lanzará una excepción.Si la tarea se está ejecutando en la última etapa del procesador, entonces la tarea habrá terminadosu ejecución, y su número desaparecerá de la estructura.En otro caso, intenta avanzar la tarea desde la réplica de la etapa en que se encuentra ejecutándosehasta alguna réplica libre de la siguiente etapa. Si no hay ninguna réplica libre de la siguienteetapa, entonces lanzará una excepción.

g) Así mismo, también deberá ser posible realizar la copia y asignación (duplicación) de la estructurade datos que representa a un determinado procesador.

7. Diseñe un programa que permita utilizar el TAD especificado en el ejercicio anterior.

15

Page 16: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Tema 4: Introducción a la Programación Orientada a Objetos1. Para calcular los sueldos de cada empleado de una factoría, se diseña la siguiente jerarquía de clases

polimórficas:

AgVentas

AgVentas_A AgVentas_B

Empleado

Directivo

Directivo_A Directivo_B

Factoria

La clase polimórfica Empleado representa un empleado general de una factoría, tiene un constructorque permite crear un objeto con el nombre (string) del empleado recibido como parámetro, yproporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• sueldo(): calcula y devuelve el sueldo del empleado. En caso de no tener información suficiente

para calcular el sueldo, entonces devolverá 0.• nombre(): devuelve el nombre del objeto empleado actual.

La clase polimórfica AgVentas representa un agente de ventas general, empleado de una factoría,tiene un constructor que permite crear un objeto con el nombre (string) del empleado recibidocomo parámetro, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• borrar_ventas(): reinicia a cero la cantidad total de ventas que acumula este agente de ventas.• anyadir_ventas(x): permite añadir una cantidad de euros recibida como parámetro a la canti-

dad total de ventas que acumula este agente de ventas.• ventas(): devuelve la cantidad total de ventas que acumula este agente de ventas.

La clase polimórfica AgVentas_A representa un agente de ventas de clase A, empleado de una factoría,tiene un constructor que permite crear un objeto con el nombre (string) del empleado recibido comoparámetro, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• sueldo(): redefine este método para calcular y devolver el sueldo de este tipo de agente de

ventas, según la siguiente ecuación:

sueldo = 2000.0 +10.0× total_ventas

100.0

La clase polimórfica AgVentas_B representa un agente de ventas de clase B, empleado de una factoría,tiene un constructor que permite crear un objeto con el nombre (string) del empleado recibido comoparámetro, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• sueldo(): redefine este método para calcular y devolver el sueldo de este tipo de agente de

ventas, según la siguiente ecuación:

sueldo = 1000.0 +5.0× total_ventas

100.0

La clase polimórfica Directivo representa un directivo general, empleado de una factoría, tieneun constructor que permite crear un objeto con el nombre (string) del empleado recibido comoparámetro, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.La clase polimórfica Directivo_A representa un directivo de clase A, empleado de una factoría, tieneun constructor que permite crear un objeto con el nombre (string) del empleado recibido comoparámetro, y proporciona los siguientes métodos públicos virtuales:

16

Page 17: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• sueldo(): redefine este método para calcular y devolver el sueldo de este tipo de directivos,según la siguiente ecuación:

sueldo = 5000.0

La clase polimórfica Directivo_B representa un directivo de clase B, empleado de una factoría, tieneun constructor que permite crear un objeto con el nombre (string) del empleado recibido comoparámetro, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• sueldo(): redefine este método para calcular y devolver el sueldo de este tipo de directivos,

según la siguiente ecuación:sueldo = 3000.0

La clase polimórfica Factoria representa una factoría con un máximo de 100 empleados, su construc-tor por defecto permite crear un nuevo objeto de clase Factoria sin ningún empleado, y proporcionalos siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• anyadir_empleado(e, ok): intenta añadir el empleado que recibe como primer parámetro (deentrada) a la lista de empleados de la factoría actual. Si la operación es posible o no, entoncesdevuelve true o false, respectivamente, en el segundo parámetro (de salida).

• sueldos(): muestra en pantalla tanto el nombre como el sueldo de cada empleado de la factoría.Finalmente, el programa principal creará un objeto de la clase Factoria, le añadirá empleados(Directivo_A, Directivo_B, AgVentas_A y AgVentas_B) y ventas acumuladas a los agentes de ven-tas, y calculará sus sueldos. Así mismo, tambien probará que la clonación de la factoría funcionaadecuadamente.

2. Se desea implementar una jerarquía de elementos gráficos como la de la siguiente figura:

ElementoGrafico

CuadradoPunto Linea

LineaVertical LineaHorizontal

La clase polimórfica ElementoGrafico representa un elemento gráfico que puede imprimirse porpantalla. Tiene un constructor por defecto que permite crear el objeto y proporciona los siguientesmétodos públicos virtuales:

• clonar(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• pintar() pinta el objeto gráfico en pantalla. En esta clase, simplemente escribe la palabra ERROR

en pantalla. Las clases derivadas deberán redefinir este método para escribir correctamente elelemento gráfico específico por pantalla.

La clase polimórfica Punto representa a un elemento gráfico especializado, en concreto a un punto(carácter ’.’), que puede imprimirse en pantalla. Suministra un constructor por defecto para crearel objeto, además de los siguientes métodos públicos virtuales:

• clonar(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• pintar(): escribe un carácter punto (’.’) y un salto de línea en pantalla.

La clase polimórfica Linea representa a un elemento gráfico especializado, en concreto una línea, quepuede imprimirse en pantalla. Suministra un constructor por defecto para crear la línea e inicializarlacon longitud cero y un constructor extendido que inicializa la línea con una determinada longitud.Además, suministra los siguientes métodos públicos virtuales:

17

Page 18: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

• clonar(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• pintar(): pinta una línea en pantalla. Las clases derivadas deberán redefinir este método paraescribir una línea específica por pantalla.

• consultar_longitud(): devuelve la longitud de la línea actual.• cambiar_longitud(lng): almacena el nuevo valor de la longitud de la línea actual recibida como

parámetro.

La clase polimórfica LineaHorizontal representa a un elemento gráfico especializado, en concretouna línea horizontal, que puede imprimirse en pantalla (como una secuencia de caracteres ’-’).Suministra un constructor por defecto para crear la línea e inicializarla con longitud cero y unconstructor extendido que inicializa la línea con una determinada longitud. Además, suministra lossiguientes métodos públicos virtuales:

• clonar(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• pintar(): pinta una línea horizontal en pantalla de la longitud almacenada en su estado: sedeben escribir en pantalla tantos caracteres ’-’ como indique su longitud, seguidos por un saltode línea.

La clase polimórfica LineaVertical representa a un elemento gráfico especializado, en concreto unalínea vertical, que puede imprimirse en pantalla (como una secuencia de caracteres ’|’ dispuestosverticalmente, es decir, separados por un ’\n’). Suministra un constructor por defecto para crearla línea e inicializarla con longitud cero y un constructor extendido que inicializa la línea con unadeterminada longitud. Además, suministra los siguientes métodos públicos virtuales:

• clonar(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• pintar(): pinta una línea vertical en pantalla de la longitud almacenada en su estado: se debenescribir en pantalla tantos caracteres ’|’ seguidos de saltos de línea como indique su longitud.

La clase polimórfica Cuadrado representa a un elemento gráfico especializado, en concreto un cuadra-do, que puede imprimirse en pantalla (empleando caracteres |, ’-’, ’ ’ y ’\n’ dispuestos en pantallade manera que simulen los lados de un cuadrado). Suministra un constructor por defecto para crearel cuadrado e inicializar su lado a cero y un constructor extendido que inicializa el cuadrado con undeterminado tamaño de lado. Además, suministra los siguientes métodos públicos virtuales:

• clonar(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• pintar(): pinta un cuadrado en pantalla empleando los caracteres |, ’-’, ’ ’ y ’\n’.• consultar_lado(): devuelve la longitud del lado del cuadrado actual.• cambiar_lado(lng): almacena el nuevo valor de la longitud del lado del cuadrado actual recibidacomo parámetro.

Desarrolle un programa principal que declare un array de objetos polimórficos de las distintas clasespolimórficas (Punto, LineaHorizontal, LineaVertical y Cuadrado) de la jerarquía de ElementoGraficoy los escriba en pantalla invocando al método virtual pintar().

3. Se desea simular el comportamiento de una serie de vehículos, por lo que se establece la siguiente jerarquíade clases:

Vehiculo

BicicletaAutomovil

Todo objeto de la clase base polimórfica Vehiculo debe guardar en su estado la siguiente informacióny definir el siguiente constructor:

• ident: identificador del vehículo (cadena de caracteres).• distancia: la distancia recorrida por el vehículo con respecto al punto de partida (origen) delmismo (unsigned).

• Vehiculo(i): inicializa el identificador del vehículo con i y su distancia a cero.

18

Page 19: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Además, el comportamiento de los objetos Vehículo queda definido por los siguientes métodos pú-blicos virtuales:

• id(): devuelve el indentificador del vehículo• consultar_dist(): devuelve un unsigned con la distancia recorrida por el vehículo• estacionar(): establece la distancia recorrida por el vehículo en 0 (origen)• tiene_energia(): indica si el vehículo tiene energía (función lógica). Debe devolver siempretrue

• mover(): incrementa en 1 el valor de la distancia recorrida por el vehículo.• clone(): devuelve un puntero a un objeto Vehiculo, copia del vehículo actual

Además, la clase Vehículo proporciona a sus clases derivadas los siguientes métodos protected,para poder manipular adecuadamente su estado interno:

• mover(x): incrementa en x el valor de la distancia recorrida por el vehículo.

La clase derivada polimórfica Automovil añade los siguientes atributos y define el siguiente construc-tor:

• DPL: constante simbólica static, de tipo unsigned, que indica la distancia que el automóvilrecorre por litro de combustible (= 50).

• deposito: atributo unsigned que guarda el número de litros de combustible del depósito delautomóvil.

• Automovil(i): inicializa el identificador del automóvil a i, su distancia a 0 y su deposito a 0.

Además, el comportamiento de los objetos Automovil queda definido por los siguientes métodospúblicos virtuales:

• tiene_energia(): redefine el método de la clase base, devolviendo true si la cantidad almace-nada en el deposito es mayor que 0.

• mover(): redefine el método de la clase base, de tal forma que si el automóvil tiene energía,entonces se mueve una distancia igual al valor de DPL, es decir, se incrementa la distancia recorridaactual sumándole a la misma el valor almacenado en la constante miembro DPL.

• repostar(ltr): incrementa la cantidad de combustible almacenada en el deposito del automóvilen ltr litros.

• clone(): devuelve un puntero a un objeto Automovil, copia del automóvil actual.

La clase derivada polimórfica Bicicleta añade los siguientes atributos y define el siguiente construc-tor:

• NUM_PLATOS: constante simbólica static, de tipo unsigned, indicando el número de platos quetiene la bicicleta.

• plato: un unsigned que indica el plato que tiene puesto en este momento la bicicleta (a mayortamaño de plato, mayor será su desplazamiento cuando la bicicleta se mueva).

• Bicicleta(i): inicializa el identificador de la bicicleta a i, su distancia a 0 y su plato a 0.

Además, el comportamiento de los objetos Bicicleta queda definido por los siguientes métodospúblicos virtuales:

• mover(): redefine el método de la clase base, de tal forma que la bicicleta se mueve una distanciaigual al valor de plato + 1, es decir, se incrementa la distancia recorrida actual sumándole a lamisma el valor de plato + 1.

• cambiar(): cambia el valor del plato, sumándole 1 y aplicando posteriormente % NUM_PLATOS(el valor del plato siempre estará entre 0 y NUM_PLATOS - 1).

• clone(): devuelve un puntero a un objeto Bicicleta, copia de la bicicleta actual.

El programa principal debe definir el tipo Vehiculos como un tipo array de NUM_VEHICULOS = 4punteros a objetos de la clase Vehiculo.

Implementar el procedimiento viajar(v, d, t), que recibe un puntero a un objeto de la claseVehiculo, un unsigned con la distancia total a recorrer por el vehículo, y devuelve, a través de unparámetro de salida el tiempo (“minutos”) que el vehículo ha tardado en llegar a su destino (si hatenido energía suficiente para llegar). Este algoritmo debe proceder de la siguiente manera:

a) Estacionar el vehículo (es decir, inicializar la distancia recorrida a 0).b) Inicializar el tiempo a 0.

19

Page 20: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

c) Mientras que el vehículo tenga energía y su distancia recorrida sea menor que la distanciasolicitada, el vehículo debe moverse (para ello, el procedimiento debe invocar la función miembromover() del objeto Vehiculo) y tiempo se incrementa en 1.

Implementar el programa principal (main), con las siguientes características:

• Declara un array mis_vehiculos de tipo Vehiculos.• Crea un objeto Automovil, con identificador "5555JJJ" y 50 litros de gasolina y pone mis_vehiculos[0]apuntando a él.

• Crea un objeto Bicicleta, con identificador "6666JJJ" y pone mis_vehiculos[1] apuntandoa él.

• Crea un objeto Bicicleta, con identificador "7777JJJ", cambia su plato y pone mis_vehiculos[2]apuntando a él.

• Crea un objeto Bicicleta, con identificador "8888JJJ", cambia su plato dos veces y ponemis_vehiculos[3] apuntando a él.

• Para todos los vehiculos que se encuentran en mis_vehiculos, debe calcular el tiempo de dura-ción del viaje para una distancia recorrida de destino 1000 invocando al procedimiento viajary, en caso de que el vehículo tuviera energía suficiente, escribe ese tiempo por pantalla (en casocontrario, se indica con un mensaje por pantalla: El vehículo x no ha podido llegar a sudestino por falta de energía)

• Un ejemplo de ejecución podría ser:

El vehículo 5555JJJ no ha podido llegar a su destino por falta de energíaTiempo vehículo 6666JJJ: 1000 minutosTiempo vehículo 7777JJJ: 500 minutosTiempo vehículo 8888JJJ: 334 minutos

4. Dada la jerarquía de clases de Vehiculo del ejercicio anterior, se debe desarrollar la clase no-polimórficaParking para gestionar un parking con un máximo de MAX = 100 vehículos (de cualquier tipo) estacionadosen él.

Los objetos de la clase Parking deben almacenar en su estado la siguiente información:

• MAX: constante simbólica static con el máximo (= 100) de vehículos que pueden estacionarseen el parking.

• parking: un array de MAX punteros a objetos de la clase Vehiculo.• n_v: número de vehículos estacionados en el parking.

Además, la clase Parking debe suministrar los siguientes métodos, constructores, etc. públicos:

• Parking(): inicializa el número de vehículos estacionados en el parking a 0.• Parking(otro_parking): constructor de copia de la clase: copia (clona) todos los vehículosestacionados en otro_parking al parking actual.

• ~Parking(): destructor de la clase: libera todos los vehículos almacenados en el parking (losdestruye).

• operator=(otro_parking): operador de asignación para la clase Parking.• anyadir(v, ok): recibe como parámetro de entrada v, un puntero a un objeto de la claseVehiculo. Si hay espacio en el parking para estacionar un nuevo vehículo, entonces v se añade alfinal de la lista de vehículos estacionados en el parking y el número de vehículos estacionados seincrementa en 1; finalmente, se debe invocar al método de estacionar sobre este nuevo vehículoestacionado (para que su distancia recorrida se ponga a 0); ok debe ponerse a true en ese caso.Si no hay espacio para estacionar en el parking, se devuelve false a través de ok.

• mostrar(): muestra por pantalla los identificadores de todos los vehículos estacionados en elparking.

• extraer(id): busca en la lista de vehículos almacenados en el parking el vehículo con idenfifi-cador id. Si lo encuentra, debe extraer el vehículo del parking y devolver un puntero al objetovehículo extraído. Si no lo encuentra, entonces devuelve NULL.

Se aconseja, además, implementar los siguientes métodos privados de la clase Parking:

• buscar(id): devuelve la posición del array parking que contiene un puntero apuntando alvehículo con identificador id, si éste está estacionado en el parking. Si no, devuelve una posiciónfuera de rango (por ejemplo, el n_v).

20

Page 21: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

• copiar(otro_parking): copia todo el estado de otro_parking (esto es, clona todos los vehículosalmacenados en él y copia su n_v) en el objeto actual. Nota: deben clonarse todos los vehículosdel objeto otro_parking para que el parking actual trabaje con copias de los mismos.

• destruir(): destruye todos los vehículos almacenados en el parking.Debe implementarse un programa principal que declare un objeto de la clase Parking y “pruebe”toda su funcionalidad: añada vehículos de distinto tipo (vehículos genéricos, automóviles y bicicletas)al parking, los muestre, los extraiga, haga una copia completa del parking, etc.

5. Se dispone de una clase base de tipo Robot, encargado, de forma general, de ensamblar piezas en undeterminado objeto. En este ejercicio, se pretende construir un “Androide”, y se dispone de robots especia-lizados (clases derivadas de Robot) en el ensamblaje de cada una de las piezas que componen el Androidefinal, tal como la cabeza, el tronco, los brazos y las piernas. Además, también se dispone de un robot quepermite ensamblar la identificación de cada androide ensamblado.

Robot

RPiernasRBrazosRTroncoRCabezaRIdent

En este primer ejercicio, el soporte donde ensamblar el androide es un simple string, donde se pueden irañadiendo las piezas que ensambla cada robot. Así, con objeto de simplificar el proceso y enfocar en losconceptos de POO (herencia, polimorfismo y vinculación dinamica), cada robot especializado ensamblauna determinada pieza, representada por el caracter de su inicial: C, T, B, P, de una forma muy simpleen el objeto a construir, añadiendo simplemente el carácter que representa a la pieza al objeto de tipostring. Por ejemplo, los dos primeros androides completamente ensamblados serían dos string con losvalores "ID1:CTBP" e "ID2:CTBP", considerando que cada identificación irá incrementando el valor de unnúmero de serie (contador).

La clase polimórfica Robot representa un robot general de ensamblaje, tiene un constructor pordefecto que permite crear un objeto, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• ensamblar(o, ok): recibe el objeto que se está ensamblando, de tipo string, como parámetrode entrada/salida, y un parámetro ok, de tipo bool, de salida, para devolver si la operación deensamblaje se ha realizado correctamente. Las clases derivadas deberán redefinir este métodopara ensamblar las piezas adecuadamente en el objeto recibido como parámetro.

La clase polimórfica RIdent representa un robot especializado en ensamblar la identificación de unandroide (un símbolo inicial de identificación, seguido por un número de serie y del símbolo dos-puntos), tiene un constructor que permite crear un objeto con el símbolo inicial de identificación(string) recibido como parámetro, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• ensamblar(o, ok): recibe el objeto que se está ensamblando, de tipo string, como parámetrode entrada/salida, y un parámetro ok, de tipo bool, de salida, para devolver si la operación deensamblaje se ha realizado correctamente. Este método asigna la secuencia de identificación (elsímbolo, el número de serie y los dos puntos) al objeto que se está ensamblando, y posteriormenteincrementará el número de serie.

La clase polimórfica RCabeza representa un robot especializado en ensamblar la cabeza de un androide(un carácter C), tiene un constructor por defecto que permite crear un objeto, y proporciona lossiguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• ensamblar(o, ok): recibe el objeto que se está ensamblando, de tipo string, como parámetrode entrada/salida, y un parámetro ok, de tipo bool, de salida, para devolver si la operación deensamblaje se ha realizado correctamente. Este método añade el símbolo de la cabeza (C) alobjeto que se está ensamblando.

La clase polimórfica RTronco representa un robot especializado en ensamblar el tronco de un androide(un carácter T), tiene un constructor por defecto que permite crear un objeto, y proporciona lossiguientes métodos públicos virtuales:

21

Page 22: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• ensamblar(o, ok): recibe el objeto que se está ensamblando, de tipo string, como parámetro

de entrada/salida, y un parámetro ok, de tipo bool, de salida, para devolver si la operación deensamblaje se ha realizado correctamente. Este método añade el símbolo del tronco (T) al objetoque se está ensamblando.

La clase polimórfica RBrazos representa un robot especializado en ensamblar los brazos de un an-droide (un carácter B), tiene un constructor por defecto que permite crear un objeto, y proporcionalos siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• ensamblar(o, ok): recibe el objeto que se está ensamblando, de tipo string, como parámetrode entrada/salida, y un parámetro ok, de tipo bool, de salida, para devolver si la operación deensamblaje se ha realizado correctamente. Este método añade el símbolo de los brazos (B) alobjeto que se está ensamblando.

La clase polimórfica RPiernas representa un robot especializado en ensamblar las piernas de unandroide (un carácter P), tiene un constructor por defecto que permite crear un objeto, y proporcionalos siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• ensamblar(o, ok): recibe el objeto que se está ensamblando, de tipo string, como parámetrode entrada/salida, y un parámetro ok, de tipo bool, de salida, para devolver si la operación deensamblaje se ha realizado correctamente. Este método añade el símbolo de las piernas (P) alobjeto que se está ensamblando.

Finalmente, el programa principal creará los 5 robots de ensamblaje especializados necesarios, losalmacenará en una cadena de montaje (un array de robots generales) en el siguiente orden (RIdent,RCabeza, RTronco, RBrazos y RPiernas), y ensamblará adecuadamente una determinada cantidadde androides, considerando que cada objeto a ensamblar se va pasando de robot en robot en la cadenade montaje hasta finalizar el ensamblaje completo del androide.

6. En este segundo ejercicio, se pretende ensamblar un androide un poco más sofisticado, con la siguienteapariencia en el objeto a construir de tipo string:

ID1o

/|\/ \

considerando que el salto de línea se puede representar con el carácter ’\n’ dentro de un string.

7. En este tercer ejercicio, se modifica el objeto a construir para facilitar y flexibilizar la construcción yensamblaje de objetos diversos. Así, se define la nueva clase no-polimórfica Objeto2D que permite elensamblaje de piezas (de tipo string) en determinadas posiciones (fila y columna) de un plano-2D (unarray de dos dimensiones donde cada elemento es de tipo char).

Lo robots, ahora, en vez de ensamblar las piezas en un objeto de tipo string, se encargarán de ensamblarlas piezas adecuadas en este Objeto2D, pudiéndose mostrar el resultado final.

ID1o

/|\/ \

La clase no-polimórfica Objeto2D representa una superficie 2D donde es posible ensamblar piezasdiversas (representadas como caracteres en un string) en determinadas posiciones de la superficie,tiene un constructor por defecto que permite crear un objeto, inicializando la superfice vacía, yproporciona los siguientes métodos públicos:

• Tanto el constructor de copia, como el operador de asignación serán generados automáticamentepor el compilador.

• id(i): recibe como parámetro y almacena el identificador asociado al objeto que se está ensam-blando.

• id(): devuelve el identificador que ha sido previamente asignado al objeto actual.

22

Page 23: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

• mostrar(): muestra en pantalla tanto el identificador del objeto, como la superficie con las piezasensambladas. Es deseable que el tamaño de la zona 2D a mostrar se restrinja al tamaño del objetoensamblado.

• ensamblar_pieza(f, c, p, ok): recibe la fila y columna indicando la posición donde ensamblarla pieza (string) recibida como tercer parámetro, y si todo es correcto, situa cada carácter de lapieza en el sitio especificado. Finalmente, un parámetro ok, de tipo bool, de salida, indicará si laoperación de ensamblaje se ha realizado correctamente. Además, es deseable que vaya registrandoel tamaño del objeto que se está ensamblando.

8. En este cuarto ejercicio, se debe definir una nueva clase no-polimórfica denominada Factoria que contieneuna cadena de robots de ensamblaje (en un array), los cuales construyen androides pasándose el Objeto2Dentre ellos a lo largo de la cadena, y finalmente el producto final se almacena en un determinado almacen(array) de Objeto2D. Estos productos finales ya ensamblados pueden ser extraidos para su utilizaciónfuera de la factoría.

La clase no-polimórfica Factoria representa una factoría con un almacen de como máximo 10Objeto2D ensamblados, y una cadena de Robot con los 5 robots de ensamblaje especializados, tieneun constructor que permite crear un objeto con el símbolo inicial de identificación (string) recibidocomo parámetro, de tal forma que todos los androides ensamblados tendrán el mismo símbolo basede identificación y construye los 5 robots especializados en la cadena de ensamblaje. Además, la claseproporciona los siguientes métodos públicos:

• Se debe implementar el constructor de copia y el operador de asignación, que permitan copiarla estructura de datos de la clase.

• construir(ok): si hay espacio en el almacen, entonces ensambla completamente un nuevo an-droide y lo almacena adecuadamente. Si la operación es posible o no, entonces devuelve true ofalse, respectivamente, en el parámetro de salida.

• mostrar_almacen(): muestra en pantalla a todos los androides ensamblados que se encuentranen el almacen.

• obtener_nobjs(): devuelve la cantidad de androides ensamblados que se encuentran en el al-macen.

• extraer(): extrae del almacen y devuelve un Objeto2D con un androide ensamblado que seencuentre en el almacen. Si no hay ningún androide ensamblado en el almacen, entonces devuelveun Objeto2D vacío.

El programa principal creará una factoría, y construirá adecuadamente una determinada cantidad deandroides, que serán almacenados en el almacen de la factoría. Finalmente, extraerá los androidesalmacenados y los mostrara por pantalla.

23

Page 24: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Tema 5: Colecciones1. Diseñe un programa que utilice el tipo vector de la biblioteca estándar para almacenar las personas de

una agenda, donde por cada persona se almacena el nombre y el teléfono. La agenda se gestiona mediantela siguientes operaciones:

Añadir los datos de una persona a la agenda, de tal forma que si la persona ya existe, entonces seactualiza su número de teléfono, y en otro caso, se añade la nueva persona y su teléfono a la agenda.

Mostrar todos los datos de la agenda.

Mostrar los datos de una determinada persona, a partir de su nombre recibido como parámetro. Encaso de que no exista en la agenda ninguna persona con dicho nombre, entonces se mostrará unmensaje de error.

Borrar los datos de una determinada persona, a partir de su nombre recibido como parámetro. Encaso de que no exista en la agenda ninguna persona con dicho nombre, entonces se mostrará unmensaje de error.

2. Realice el ejercicio anterior, utilizando el TAD Persona definido en la práctica 7 (agenda-hash), e imple-mentando el TAD Agenda de la misma práctica con vector en vez de con una lista enlazada.

3. Diseñe un programa que lea y almacene en un vector de la biblioteca estándar las ventas realizadas porunos agentes de ventas. Leerá el nombre y el total de ventas que ha realizado, hasta leer un nombre deagente vacío. Posteriormente se eliminarán del vector aquellos agentes cuyas ventas sean inferiores a lamedia de las ventas realizadas. Finalmente se mostrará el contenido del vector.

4. Diseñe un programa que lea dos matrices de números reales de tamaños arbitrarios (primero leerá lasdimensiones y posteriormente los elementos de la matriz) y muestre el resultado de multiplicar ambasmatrices. Las matrices se almacenarán en vectores de dos dimensiones (utilizando el tipo vector de labiblioteca estándar).

5. Diseñe un programa que lea una expresión aritmética que contiene llaves {}, paréntesis () y corchetes []y compruebe si éstos se encuentran correctamente equilibrados o no. Por ejemplo la siguiente expresión3 + 5 ∗ ([4]− 67) + [(7)] se encuentra correctamente equilibrada, donde los posibles casos de error son lossiguientes:

Un símbolo de apertura no se corresponde con su correspondiente símbolo de cierre. Por ejemplo:3 + 5 ∗ ([4]− 67] + [(7)]

Para un determinado símbolo de apertura, no existe el correspondiente símbolo de cierre. Por ejemplo:(3 + 5 ∗ ([4]− 67 + [(7)])

Para un determinado símbolo de cierre, no existe el correspondiente símbolo de apertura. Por ejemplo:(3 + 5 ∗ [4]− 67) + [(7)])

24

Page 25: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Prácticas de Laboratorio

Práctica 1: Almacenamiento Persistente de Datos1. Diseñe un programa que gestione una agenda que almacene información sobre personas (nombre y edad),

permita añadir, modificar y eliminar personas desde el teclado, así como mostrar el contenido de la agenda.Adicionalmente, el programa permitirá cargar el contenido de la agenda desde un fichero, así como guardarel contenido de la agenda a un fichero.

Se diseñarán versiones para trabajar con tres formatos de ficheros diferentes (donde los símbolos y ←↩

representan el espacio en blanco y el fin de línea respectivamente):

Opción (A) Opción (B) Opción (C)

nombre_apellidos edad ←↩

nombre_apellidos edad ←↩

· · ·

nombre apellidos ←↩

edad ←↩

nombre apellidos ←↩

edad ←↩

· · ·

nombre apellidos edad ←↩

nombre apellidos edad ←↩

· · ·

Nótese que en la primera opción (A), el nombre de la persona no contiene espacios en blanco, mientrasque en las siguientes opciones (B y C), si es posible que el nombre de la persona contenga espacios enblanco.

El programa mostrará un menú iterativo para poder seleccionar las acciones deseadas por el usuario delprograma, tal como:

#include <iostream>#include <fstream>#include <string>#include <array>#include <cctype>using namespace std;

struct Persona {string nombre;unsigned edad;

};const unsigned MAX = 100;typedef array<Persona , MAX> APers;struct Agenda {

unsigned nelms;APers elm;

};// . . . . . . a completar por e l alumno . . . . . . . . . . . .char menu(){

char op;cout << endl;cout << "C. Cargar Agenda desde Fichero" << endl;cout << "G. Guardar Agenda en Fichero" << endl;cout << "M. Mostrar Agenda en Pantalla" << endl;cout << "A. Anadir Persona a la Agenda" << endl;cout << "X. Fin" << endl;do {

cout << endl << " Opcion: ";cin >> op;op = char(toupper(op));

} while (!((op == 'C')||(op == 'G')||(op == 'M')||(op == 'A')||(op == 'X')));cout << endl;return op;

}

int main(){

Agenda ag;char op;inic_agenda(ag);do {

op = menu ();switch (op) {case 'C':

cargar_agenda(ag);

25

Page 26: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

break;case 'G':

guardar_agenda(ag);break;

case 'M':escribir_agenda(ag);break;

case 'A':nueva_persona(ag);break;

}} while (op != 'X');

}

26

Page 27: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Práctica 2: Tipos Abstractos de Datos (I)1. Diseñe e implemente un TAD para números racionales. Se deberán seguir las siguientes consideraciones:

Los números racionales se representan mediante fracciones, donde tanto el numerador como denomi-nador son de tipo int).

Las fracciones se representarán en todo momento normalizadas (simplificadas):

• Es recomendable implementar un método privado de simplificación de la fracción mediante elcálculo del máximo común divisor (m.c.d.) del numerador y el denominador y su posterior divisiónpor dicho m.c.d.Para calcular el máximo común divisor de dos numeros enteros positivos n y m, el algoritmo deEuclides funciona como se indica a continuación:a) Si n < m, entonces se intercambian los valores de n y m (para asegurarnos que n siempre sea mayor

o igual que m).b) Si el valor de m es distinto de 0, entonces sea r el resto de la división entera entre n y m; después

modificamos los valores de n y m de la siguiente forma: n toma ahora el valor de m y m toma ahorael valor de r (el resto de la división entera entre n y m calculado anteriormente), y se repite esteproceso especificado hasta que el valor de m sea igual a 0.

c) Finalmente, cuando el proceso iterativo acaba, el valor de n es el máximo común divisor de ambosnúmeros.

• Para simplificar la determinación del signo de la fracción puede asumirse que el denominador dela fracción es siempre positivo (por lo que una fracción de signo negativo tendrá un numeradorde signo negativo y un denominador de signo positivo).

El cero se guardará siempre en su forma canónica 0/1.

Por defecto, un número racional debe asignarse a cero cuando se crea.

Debe evitarse en todo momento la asignación de cero a un denominador.

Un determinado método permitirá comprobar si un determinado número racional se encuentra enestado de error. Un denominador igual a cero (0) se considera un estado de error.

Debe poder ser posible crear números racionales especificando su numerador y denominador, comosólamente especificando su numerador (en este último caso, se considerará un denominador igual a1).

class Racional {public:

Racional () ;// Construye e l numero rac iona l 0/1

Racional(int n) ;// Construye e l numero rac iona l n/1

Racional(int n, int d) ;// Construye e l numero rac iona l n/d

bool fail() const;// Devuelve t rue s i e l numero rac iona l a c tua l e s t a en es tado erroneo

void multiplicar(const Racional& r1, const Racional& r2);// Asigna a l numero rac iona l a c tua l e l r e su l t ado de// mu l t i p l i c a r l o s numeros rac i ona l e s ( r1 ) y ( r2 )

void escribir () const;// Muestra en pan t a l l a e l va l o r de l numero rac iona l a c tua l

void leer ();// Lee de t e c l ado e l va l o r de l numero rac iona l a c tua l

private:void normalizar ();

};

2. Diseñe un programa que permita utilizar el TAD especificado en el ejercicio anterior.

3. Añada de forma incremental los siguientes métodos públicos al TAD Racional realizado anteriormente:

class Racional {public:

// . . .void dividir(const Racional& r1, const Racional& r2);

// Asigna a l numero rac iona l a c tua l e l r e su l t ado de// d i v i d i r l o s numeros rac i ona l e s ( r1 ) y ( r2 )

27

Page 28: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

void sumar(const Racional& r1 , const Racional& r2);// Asigna a l numero rac iona l a c tua l e l r e su l t ado de// sumar l o s numeros rac i ona l e s ( r1 ) y ( r2 )

void restar(const Racional& r1 , const Racional& r2);// Asigna a l numero rac iona l a c tua l e l r e su l t ado de// r e s t a r l o s numeros rac i ona l e s ( r1 ) y ( r2 )

bool igual(const Racional& r1) const;// Devuelve t rue s i e l numero rac iona l a c tua l es i g u a l a ( r1 )

bool menor(const Racional& r1) const;// Devuelve t rue s i e l numero rac iona l a c tua l es menor que ( r1 )

};

4. Modifique el programa que utiliza el TAD Racional especificado anteriormente para que utilice los nuevosmétodos añadidos anteriormente.

28

Page 29: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Práctica 3: Tipos Abstractos de Datos (II)1. Diseñe e implemente un TAD Punto del plano cartesiano en el espacio de nombres umalcc, considerando

que un Punto describe una determinada posición en el plano cartesiano, especificada por el valor de lascomponentes X e Y de las coordenadas cartesianas, y proporciona los siguientes métodos públicos. En laimplementación del TAD Punto, se recomienda la implementación en el espacio de nombres anónimo de lafunción double sq(double x) (devuelve x2) y de la función double hipotenusa(double a, double b)(devuelve

√a2 + b2).

class Punto {public:

˜ Punto ();// des t ruye e l o b j e t o ac tua l y sus recursos asoc iados .

Punto ();// crea un punto en e l or igen de coordenadas .

Punto(double cx, double cy);// crea un punto en l a s coordenadas r e c i b i d a s como parametros .

Punto(const Punto& o);// crea un punto copiando sus va l o r e s de l o b j e t o r e c i b i d o como// parametro .

Punto& operator=(const Punto& o);// asigna a un ob j e t o punto e l va l o r de otro ob j e t o punto// r e c i b i d o como parametro .

void desplazar(double dx, double dy);// Desplaza e l o b j e t o ac tua l desde l a pos i c ion ac tua l una// determinada d i s t anc i a e s p e c i f i c a da como parametros en ambos e j e s .

double distancia(const Punto& o) const;// devue l ve l a d i s t anc i a ab so l u t a entre e l o b j e t o ac tua l y e l// ob j e t o punto r e c i b i d o como parametro .

double coord_x () const;// devue l ve e l va l o r de l a componente X de l o b j e t o ac tua l .

double coord_y () const;// devue l ve e l va l o r de l a componente Y de l o b j e t o ac tua l .

};

2. Diseñe un programa que permita comprobar el funcionamiento del TAD especificado en el ejercicio anterior.

3. Diseñe e implemente un TAD Segmento del plano cartesiano en el espacio de nombres umadpt, considerandoque un Segmento es un fragmento de una recta que se encuentra comprendido entre dos Puntos (origen ydestino) en el plano cartesiano, y proporciona los siguientes métodos públicos:

class Segmento {public:

˜ Segmento ();// des t ruye e l o b j e t o ac tua l y sus recursos asoc iados .

Segmento ();// crea un ob j e t o Segmento nulo , donde ambos puntos que// l o de l imi tan se encuentran en e l or igen de coordenadas .

Segmento(double x1, double y1, double x2, double y2);// crea un ob j e t o Segmento según l o s va l o r e s de l a s 4// coordenadas de dos puntos e s p e c i f i c a d o s como parámetros .

Segmento(const Punto& o, const Punto& d);// crea un ob j e t o Segmento segun l o s va l o r e s de dos puntos// e s p e c i f i c a d o s como parametros .

Segmento(const Segmento& o);// crea un Segmento copiando sus va l o r e s de l o b j e t o r e c i b i d o// como parametro .

Segmento& operator=(const Segmento& o);// asigna a un ob j e t o Segmento e l va l o r de otro ob j e t o Segmento// r e c i b i d o como parametro .

void desplazar(double dx, double dy);// Desplaza e l o b j e t o ac tua l desde l a pos i c ion ac tua l una// determinada d i s t anc i a e s p e c i f i c a da como parametros en ambos e j e s .

double longitud () const;// devue l ve l a l ong i t ud de l o b j e t o Segmento .

Punto origen () const;// devue l ve e l va l o r de l Punto or igen de l Segmento ac tua l .

Punto destino () const;// devue l ve e l va l o r de l Punto de s t ino de l Segmento ac tua l .

};

29

Page 30: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

4. Diseñe un programa que permita comprobar el funcionamiento del TAD especificado en el ejercicio anterior.

5. Diseñe e implemente un TAD Polígono del plano cartesiano en el espacio de nombres umalcc, considerandoque un Polígono es una figura plana compuesta por una secuencia finita de lados consecutivos determinadospor vértices (Puntos) en el plano cartesiano, y proporciona los siguientes métodos públicos:

class Poligono {public:

˜ Poligono ();// des t ruye e l o b j e t o ac tua l y sus recursos asoc iados .

Poligono ();// crea un ob j e t o Pol igono vacio , s in v e r t i c e s ni l ados .

Poligono(const Poligono& o);// crea un Poligono copiando sus va l o r e s de l o b j e t o r e c i b i d o// como parametro .

Poligono& operator=(const Poligono& o);// asigna a un ob j e t o Pol igono e l va l o r de otro ob j e t o Pol igono// r e c i b i d o como parametro .

void nuevo_vertice(const Punto& v);// agrega un nuevo v e r t i c e a l o b j e t o Pol igono ac tua l .

void mover_vertice(int pos , const Punto& v);// cambia l a pos i c ion de l v e r t i c e e s p e c i f i c a do en e l primer// parametro de l o b j e t o actua l , por e l nuevo va l o r// e s p e c i f i c a do e l e l segundo parametro .

void desplazar(double dx, double dy);// desp la za e l o b j e t o ac tua l desde l a pos i c ion ac tua l una// determinada d i s t anc i a e s p e c i f i c a da como parametros en ambos// e j e s .

double perimetro () const;// devue l ve e l perimetro de l o b j e t o ac tua l .

Punto vertice(int pos) const;// devue l ve e l va l o r de l v e r t i c e e s p e c i f i c a do en e l primer// parametro .

Segmento lado(int pos) const;// devue l ve e l va l o r de l lado e s p e c i f i c a do en e l primer// parametro .

int n_vertices () const;// devue l ve e l numero de v e r t i c e s de l po l i gono ac tua l .

};

6. Diseñe un programa que permita comprobar el funcionamiento del TAD especificado en el ejercicio anterior.

30

Page 31: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Práctica 4: Tipos Abstractos de Datos (III)1. Diseñe e implemente un TAD (Cuenta) bancaria que represente una cuenta bancaria de un cliente de un

banco. Así, almacena el nombre del cliente (cadena de caracteres), el número de cuenta (número entero)y el saldo de la cuenta (número real), de tal forma que gestione su manipulación segura, especialmenteconsiderando que no se puede quedar con saldo negativo.

El TAD Cuenta se definirá en el espacio de nombres umalcc_1, y deberá proporcionar métodos públicosque soporten adecuadamente las siguientes operaciones. Diseñe también un programa que permita suutilización.

class Cuenta {public:

Cuenta ();// crea una cuenta con va l o r e s por de f e c t o .

Cuenta(const std:: string& n, int c, double s);// crea una cuenta con l o s va l o r e s r e c i b i d o s como parametros .

bool error() const;// devue l ve f a l s e s i l a cuenta es correcta , y t rue s i l a cuenta// es erronea (nombre vac io o numero de cuenta nega t i vo o sa ldo// nega t i vo ) .

void mostrar () const;// muestra en pan t a l l a toda l a informacion asociada a l a// cuenta bancaria . En caso de cuenta erronea , mostrara un// mensaje adecuado .

std:: string obtener_nombre () const;// devue l ve e l va l o r de l nombre de l o b j e t o cuenta .

int obtener_cuenta () const;// devue l ve e l va l o r de l numero de cuenta de l o b j e t o cuenta .

double obtener_saldo () const;// devue l ve e l va l o r de l sa ldo de l o b j e t o cuenta .

};

2. Diseñe un programa que permita comprobar el funcionamiento del TAD especificado en el ejercicio anterior.

3. Diseñe e implemente un TAD (Banco) que represente las cuentas bancarias de los clientes de un banco,utilizando para ello el TAD Cuenta bancaria diseñado en el apartado anterior.

Así, el TAD Banco se encargará de la gestión del global de cuentas a nivel del banco y considerandomúltiples clientes, utilizando para cada uno de ellos el TAD Cuenta, el cual se encargará de la manipulaciónde la cuenta de un usuario, controlando que operaciones son válidas y cuales no.

Así, para cada cliente, se almacena su nombre (cadena de caracteres), el número de cuenta (número entero)y el saldo de la cuenta (número real), teniendo en cuenta que nunca podrá existir un saldo negativo. Paraello, el TAD Banco contiene un array para almacenar las cuentas bancarias (TAD Cuenta) de cadacliente, así como tambien almacena el número de cuentas bancarias que tiene actualmente activas (todasalmacenadas consecutivamente desde el principio del array). Además, también contiene un número quesirve para asignar números de cuenta consecutivos a las cuentas bancarias que se vayan creando.

El tipo abstracto de datos deberá permitir tanto crear nuevas cuentas bancarias como eliminarlas. Asímismo, deberá permitir mostrar los datos de las cuentas bancarias almacenadas.

El TAD Banco se definirá en el espacio de nombres umalcc_2, y deberá proporcionar métodos públicosque soporten adecuadamente las siguientes operaciones:

class Banco {public:

Banco ();// crea un banco vacio , s in c l i e n t e s , i n i c i a l i z a n d o// adecuadamente e l contador para as ignar numeros de cuenta .

void crear_cuenta(const std:: string& nombre , int& num , bool& ok);// crea una cuenta bancaria para una determinada persona ,// u t i l i z a n d o su nombre e s p e c i f i c a do como parametro . El numero// de cuenta se c a l c u l a a p a r t i r de un va l o r almacenado en l o s// a t r i b u t o s de l banco , que l l e v a una cuenta incrementa l de l o s// numeros de cuentas previamente as ignados . Devolvera en un// parametro de s a l i d a e s t e numero de cuenta asignado por e l// banco . Si l a operacion se r e a l i z o correc ta o incorrectamente ,// sera no t i f i c a do mediante un parametro de s a l i d a .

void eliminar_cuenta(int num , bool& ok);// e l imina una cuenta bancaria a p a r t i r de un numero de cuenta

31

Page 32: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

// e s p e c i f i c a do como parametro . Si l a operacion se r e a l i z o// correc ta o incorrectamente , sera no t i f i c a do mediante un// parametro de s a l i d a .

void mostrar_cuentas () const ;// muestra toda l a informacion almacenada en l a e s t ruc tu ra// de datos .

};

4. Diseñe un programa que permita utilizar el TAD especificado en el ejercicio anterior.

5. Añada de forma incremental los siguientes métodos públicos al TAD Cuenta realizado anteriormente, detal forma que deberá permitir realizar ingresos y retirar efectivo de la cuenta bancaria. Además, tambiénpermitirá aplicar un determinado interés al saldo, así como cobrar unos gastos de comisión. Considerandoque si la cuenta se encuentra en estado erróneo, la operación será errónea y no se realizará ningunaoperación. Además, si la operación se realizó correcta o incorrectamente, será notificado mediante unparámetro de salida.

class Cuenta {public:

// . . .void ingresar_saldo(double cant , bool& ok);

// ingre sar una determinada cant idad de dinero e s p e c i f i c a da// como parametro , para sumar a l sa ldo de l a cuenta .

void retirar_saldo(double cant , bool& ok);// r e t i r a r una determinada cant idad de dinero e s p e c i f i c a da// como parametro de l sa ldo de l a cuenta , considerando que e l// sa ldo nunca podra ser nega t i vo .

void ingresar_interes(double porcentaje , bool& ok);// incrementara e l sa ldo de l a cuenta en un determinado// porcen ta j e e s p e c i f i c a do como parametro .

void retirar_comision(double cant , bool& ok);// r e t i r a de l sa ldo una cant idad e s p e c i f i c a da como parametro ,// considerando que s i l a cant idad a r e t i r a r es mayor que// e l sa ldo d i spon i b l e , s o l o r e t i r a r a l a cant idad de sa ldo// d i s p on i b l e .

};

6. Añada de forma incremental los siguientes métodos públicos al TAD Banco realizado anteriormente,considerando que nunca podrá existir un saldo negativo. El tipo abstracto de datos deberá permitirrealizar ingresos y retirar efectivo de una determinada cuenta bancaria, así como realizar transferencias deefectivo de una cuenta a otra. Además, también permitirá aplicar un determinado interés a los saldos de lascuentas bancarias existentes, cobrar unos gastos de comisión, y mostrar los datos de las cuentas bancariasalmacenadas (para un determinado nombre de cliente, y para un determinado número de cuenta). Asímismo, también permitirá guardar y cargar los datos de ficheros.

class Banco {public:

// . . .void mostrar_cuenta(int num , bool& ok) const;

// muestra en pan t a l l a toda l a informacion asociada a l a// cuenta bancaria cuyo numero de cuenta se e s p e c i f i c a como// parametro . Si l a operacion se r e a l i z o correc ta o// incorrectamente , sera no t i f i c a do mediante un parametro de// s a l i d a .

void mostrar_cuentas(const std:: string& nombre) const;// muestra en pan t a l l a toda l a informacion asociada a todas// l a s cuentas bancar ias de de una persona cuyo nombre se// e s p e c i f i c a como parametro .

void ingreso(int num , double cantidad , bool& ok);// ingresa una determinada cant idad de dinero e s p e c i f i c a da// como parametro a un determinado numero de cuenta e s p e c i f i c a do// como parametro . Si l a operacion se r e a l i z o correc ta o// incorrectamente , sera no t i f i c a do mediante un parametro de// s a l i d a .

void retirar(int num , double cantidad , bool& ok);// r e t i r a una determinada cant idad de dinero e s p e c i f i c a da como// parametro de un determinado numero de cuenta e s p e c i f i c a do como// parametro , considerando que e l sa ldo nunca podra ser nega t i vo .// Si l a operacion se r e a l i z o correc ta o incorrectamente , sera// no t i f i c a do mediante un parametro de s a l i d a .

32

Page 33: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

void transferir(int dest , int origen , double cantidad , bool& ok);// t r a n s f i e r e una determinada cant idad de dinero e s p e c i f i c a da// como parametro desde un numero de cuenta or igen a otro numero// de cuenta des t ino , ambos e s p e c i f i c a d o s como parametros ,// considerando que e l sa ldo nunca podra ser nega t i vo . Si l a// operacion se r e a l i z o correc ta o incorrectamente , sera// no t i f i c a do mediante un parametro de s a l i d a .

void ingresar_intereses(double porcentaje );// ingresa l o s i n t e r e s e s en todas l a s cuentas de l banco , para// un determinado porcen ta je e s p e c i f i c a do como parametro .

void gastos_comision(double cantidad );// carga l o s gas to s de comision en todas l a s cuentas de l// banco , una cant idad que se e s p e c i f i c a como parametro . Si// l a cant idad a cargar excede de l sa ldo que una determinada// cuenta posee , entonces se l e r e t i r a r a toda l a cant idad de// sa ldo que posea .

void guardar_cuentas_fich(const std:: string& nombre_fich , bool& ok) const;// guarda toda l a informacion almacenada en l a e s t ruc tu ra de// datos en e l f i c h e r o cuyo nombre se e s p e c i f i c a como parametro ,// en un formato adecuado para pos ter iormente poder recuperar l a// informacion almacenada . Si l a operacion se r e a l i z o correc ta o// incorrectamente , sera no t i f i c a do mediante un parametro de// s a l i d a .

void cargar_cuentas_fich(const std:: string& nombre_fich , bool& ok) ;// carga toda l a informacion de l a e s t ruc tu ra de datos desde// e l f i c h e r o cuyo nombre se e s p e c i f i c a como parametro , s i gu i endo// e l formato u t i l i z a d o en l a operacion an t e r i o r . Si l a// operacion se r e a l i z o correc ta o incorrectamente , sera// no t i f i c a do mediante un parametro de s a l i d a .

};

7. Modifique el programa que utiliza el TAD Banco especificado anteriormente para que utilice los nuevosmétodos añadidos anteriormente.

33

Page 34: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Práctica 5: Gestión de Memoria Dinámica1. Diseñe un módulo (programación modular) que proporcione soporte adecuado a la manipulación de listas

enlazadas en memoria dinámica (véase siguiente figura). El módulo deberá definir el tipo PNodo como unpuntero a un registro en memoria dinámica de tipo Nodo que contiene un enlace al siguiente nodo, asícomo un dato de tipo int. Además, el módulo deberá definir los siguientes subprogramas. Diseñe tambiénun módulo principal que permita comprobar la corrección del módulo lista implementado.

lista: −−→◦ −−−−→◦0

−−−−→◦1

�2

void inicializa(PNodo& lista) ;// I n i c i a l i z a ( l i s t a ) a una l i s t a vac ia

void destruir(PNodo& lista) ;// Destruye todos l o s e lementos de l a l i s t a , l i b e rando// todos l o s nodos de memoria dinamica . ( l i s t a ) queda vac ia

void escribir(PNodo lista) ;// Muestra en pan t a l l a e l contenido de ( l i s t a )

PNodo buscar(PNodo lista , int dt) ;// Devuelve un puntero a l nodo que cont iene e l elemento// i g u a l a ( dt ) . Si no se encuentra , entonces devue l ve NULL

void insertar_principio(PNodo& lista , int dt) ;// Inse r ta un elemento a l p r i n c i p i o de ( l i s t a )

void insertar_final(PNodo& lista , int dt) ;// Inse r ta un elemento a l f i n a l de ( l i s t a )

void insertar_ord(PNodo& lista , int dt) ;// Inse r ta un elemento de forma ordenada en ( l i s t a ) , que debe e s t a r ordenada

void eliminar_primero(PNodo& lista) ;// Elimina e l primer elemento de ( l i s t a ) , s i e x i s t e

void eliminar_ultimo(PNodo& lista) ;// Elimina e l u l t imo elemento de ( l i s t a ) , s i e x i s t e

void eliminar_elem(PNodo& lista , int dt) ;// Elimina de ( l i s t a ) e l primer elemento i g u a l a ( dt ) , s i e x i s t e

PNodo situar(PNodo lista , int pos) ;// Devuelve un puntero a l nodo que se encuentra en l a pos i c ion// indicada por ( pos ) . La pos i c ion cero (0) ind i ca e l primer nodo .// Si e l nodo no ex i s t e , entonces devue l ve NULL

void insertar(PNodo& lista , int pos , int dt) ;// Inse r ta en ( l i s t a ) un elemento en l a pos i c ion indicada por ( pos )

void eliminar(PNodo& lista , int pos) ;// Elimina de ( l i s t a ) e l e lemento de l a pos i c ion indicada por ( pos ) , s i e x i s t e

PNodo duplicar(PNodo lista) ;// Devuelve un puntero a una nueva l i s t a r e su l t ado de dup l i c a r en// memoria dinamica l a l i s t a r e c i b i d a como parametro

PNodo leer() ;// Devuelve una l i s t a con l o s numeros l e i d o s de t e c l ado ( en e l mismo// orden que son in t roduc ido s ) hasta que l e a e l numero 0 ( que no es// in t roduc ido )

void eliminar_mayor(PNodo& lista) ;// Elimina e l mayor elemento de ( l i s t a ) , s i e x i s t e

void purgar(PNodo& lista , int dt) ;// Elimina de ( l i s t a ) todos l o s e lementos que sean i g u a l e s a ( dt ) , s i e x i s t e n

34

Page 35: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Práctica 6: Abstracción en la Gestión de Memoria Dinámica (I)1. Diseñe un TAD Dato en el espacio de nombres umadpt que contiene un valor de tipo entero, y defina los

siguientes métodos:

Destructor: destruye y libera los recursos asociados al objeto.

Constructor por defecto: construye un objeto con valor cero.

Constructor específico: construye un objeto con el valor recibido como parámetro.

Constructor de copia: copia el contenido de otro objeto.

Operador de asignación: asigna el contenido de otro objeto.

Acceder: método constante que devuelve el valor contenido en el objeto.

Modificar: cambia el valor contenido en el objeto por el valor recibido como parámetro.

2. Diseñe un TAD BolsaDato en el espacio de nombres umalcc que contiene una colección de elementoshomogéneos (de tipo Dato de umadpt), y defina los siguientes métodos:

Destructor: destruye y libera los recursos asociados a la bolsa.

Constructor por defecto: construye una bolsa vacía.

Constructor de copia: copia el contenido de otra bolsa.

Operador de asignación: asigna el contenido de otra bolsa.

Size: método constante que devuelve el número de elementos almacenados en la bolsa.

Clear: elimina los elementos almacenados, dejando la bolsa vacía.

Mostrar: método constante que muestra en pantalla el contenido de la bolsa.

Añadir: añade el dato recibido como parámetro a la bolsa.

Eliminar: elimina un elemento de la bolsa que sea igual al valor del dato recibido como parámetro.

Pertenece: método constante que devuelve true si el dato recibido como parámetro se encuentra enla bolsa, y false en cualquier otro caso.

Cambiar: cambia el valor de todos los elementos de la bolsa que son iguales al primer dato recibidocomo parámetro por el valor del segundo dato recibido como parámetro.

Extraer: elimina de la bolsa todos los elementos iguales al valor del dato recibido como parámetro, ydevuelve la cuenta del número de elementos eliminados.

3. Diseñe un programa que permita utilizar el TAD especificado en el ejercicio anterior.

35

Page 36: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Práctica 7: Abstracción en la Gestión de Memoria Dinámica (II)1. Diseñe e implemente un TAD Persona, que almacene el nombre y el teléfono de una persona (ambos de

tipo cadena de caracteres), y proporcione los siguientes métodos publicos:

class Persona {public:

˜ Persona () ;// Destruye e l o b j e t o y todos sus recursos asoc iados .

Persona () ;// Construye una persona con nombre y t e l e f o no vac io .

Persona(const std:: string& n, const std:: string& t) ;// Construye una persona con e l nombre y e l t e l e f o no// segun l o s parametros r e c i b i d o s .

bool error() const;// Devuelve t rue s i e l o b j e t o ac tua l e s ta en es tado erroneo ,// es decir , e l nombre o e l t e l e f o no son vac io s .

std:: string obtener_nombre () const;// Devuelve e l va l o r de l nombre de l o b j e t o ac tua l .

std:: string obtener_telefono () const;// Devuelve e l va l o r de l t e l e f o no de l o b j e t o ac tua l .

};

2. Diseñe e implemente un TAD Agenda que, utilizando el TAD Persona definido anteriormente, almaceneel nombre y teléfono de múltiples personas, y permita su acceso de forma adecuada. La agenda se puedeimplementar eficientemente utilizando técnicas hash, de la siguiente forma:

Cuando se quiere almacenar una nueva persona, se calcula el número que proporciona la función hashaplicada al nombre de la persona, y posteriormente se añade la persona a la lista enlazada que seencuentra en la posición indicada por el número hash calculado (véase ejemplo a continuación).

Cuando se quiere acceder a una determinada persona, se calcula el número que proporciona la funciónhash aplicada al nombre de la persona, y se busca la persona en la lista enlazada que se encuentraen la posición indicada por el número hash calculado (véase ejemplo a continuación).

Cuando se quiere borrar a una determinada persona, se calcula el número que proporciona la funciónhash aplicada al nombre de la persona, y se elimina la persona con ese nombre de la lista enlazada quese encuentra en la posición indicada por el número hash calculado (véase ejemplo a continuación).

Por ejemplo, la función hash para el nombre de la persona puede ser la siguiente, donde el primer parámetroespecifica el nombre de la persona, y el segundo parámetro especifica el tamaño del array de listas enlazadas:

unsigned hash(const std:: string& nombre , unsigned tamanyo){

unsigned valor = 0;for (unsigned i = 0; i < nombre.size (); ++i) {

valor = valor * 7 + unsigned(nombre[i]);}return valor % tamanyo;

}

Por ejemplo, dado un tamaño del array de 5, si la función hash para los nombres pepe, maria y anaproporciona el valor 0, para el nombre juan proporciona el valor 2 y para los nombres lola y jaimeproporciona el valor 4, tendríamos la estructura que se muestra a continuación:

6nelms

elms0

1

2

3

4

30

pepe

22

maria

35

ana

37

jaime

23

lola

27

juan

El TAD Agenda debe proporcionar los siguientes métodos públicos:

36

Page 37: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

class Agenda {public:

˜ Agenda () ;// Destruye e l o b j e t o y todos sus recursos asoc iados .

Agenda () ;// Construye una agenda vac ia .

void anyadir(const Persona& p);// Si l a persona e s p e c i f i c a da como parametro no es ta en modo// erroneo , s i l a persona ya se encontraba en l a agenda ,// entonces l o s nuevos va l o r e s de l a persona reemplazan a l o s// anter iore s , en otro caso anyade l a persona e s p e c i f i c a da a// l a agenda ac tua l .

Persona buscar(const std:: string& nombre) const;// Busca en l a agenda l a persona cuyo nombre se e s p e c i f i c a// como parametro , y s i l a encuentra , entonces devue l ve un ob j e t o// Persona con l o s va l o r e s de l a persona almacenados . Si no// l a encuentra , entonces devue l ve una persona en es tado de// error .

void eliminar(const std:: string& nombre , bool& ok);// Elimina de l a agenda ac tua l l a persona cuyo nombre se// e s p e c i f i c a como parametro y ok tomara e l va l o r t rue . En caso// de no e x i s t i r , ok tomara e l va l o r f a l s e .

void mostrar () const;// Muestra en pan t a l l a e l contenido completo de l a agenda .

};

3. Diseñe un programa que permita utilizar el TAD especificado en el ejercicio anterior.

37

Page 38: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Práctica 8: Introducción a la Programación Orientada a Objetos1. Se dispone de la siguiente jerarquía de clases para gestionar los coches de un concesionario de coches.

Coche

CocheOcasion Importado

Coche

Concesionario

La clase polimórfica Coche representa un determinado modelo de coche, tiene un constructor quepermite crear un objeto con el nombre (string) y el precio base (double) del modelo del cocherecibidos como parámetros, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• obtener_modelo(): devuelve el nombre del modelo del objeto actual.• calc_precio(): calcula y devuelve el precio del coche actual, según la siguiente ecuación:

precio = precio_base

• mostrar(): muestra en pantalla la información del objeto actual, según el formato del siguienteejemplo (sin salto de línea): (Porsche-911, 40000), considerando que el acceso a la informaciónse realizará invocando a los metodos adecuados.

La clase polimórfica CocheOcasion representa un coche de ocasión, que es-un coche con un porcen-taje de descuento. Para ello, tiene un constructor que permite crear un objeto con el nombre (string),el precio base (double) y el porcentaje de descuento (double) del modelo del coche recibidos comoparámetros, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• obtener_descuento(): devuelve el porcentaje de descuento que se aplicará cuando se calcule elprecio del objeto actual.

• calc_precio(): calcula y devuelve el precio del coche actual, según la siguiente ecuación:

precio = precio_base − precio_base × porcentaje ÷ 100

La clase polimórfica CocheImportado representa un coche de importado, que es-un coche con uncoste de homologación adicional. Para ello, tiene un constructor que permite crear un objeto con elnombre (string), el precio base (double) y el coste de homologación (double) del modelo del cocherecibidos como parámetros, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• obtener_homologacion(): devuelve el coste de homologacion que se aplicará cuando se calculeel precio del objeto actual.

• calc_precio(): calcula y devuelve el precio del coche actual, según la siguiente ecuación:

precio = precio_base + coste_homologacion

La clase polimórfica Concesionario representa un concesionario de coches, de tal forma que puedecontener múltiples coches de diversas clases. Para ello, tiene un constructor que permite crear unobjeto concesionario vacío, sin coches, y proporciona los siguientes métodos públicos virtuales:

• clone(): devuelve un puntero a un nuevo objeto creado como copia del objeto actual.• anyadir(): recibe como parámetro un puntero a un objeto coche, y comprueba si ya está alma-cenado un coche con el mismo nombre de modelo, en cuyo caso reemplaza el coche anterior porel nuevo recibido como parámetro (atención a la pérdida de recursos). Sin embargo, si no hay uncoche con el mismo nombre de modelo, entonces. si cabe, lo añade al concesionario. Finalmentedevuelve en un parámetro de salida true si la operación se ha realizado adecuadamente y falseen otro caso.

• calc_precio(): recibe como parámetro el nombre de un modelo, y, si existe, devuelve el preciode dicho modelo. En caso de que no exista dicho modelo, entonces devuelve el valor -1.

38

Page 39: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

• seleccionar_barato(): calcula y devuelve un puntero al objeto coche que tenga el menor preciode todos los almacenados en el concesionario. Si no hay coches almacenados, entonces devuelveNULL.

• mostrar(): muestra en pantalla la información de todos los coches almacenados en el objetoactual, invocando al método mostrar sobre cada coche, según el formato del siguiente ejemplo:{ (Seat-Marbella, 7200), (Seat-Leon, 15000), (Porsche-911, 40000) }

• Hay que considerar que el destructor del concesionario debe destruir todos los coches allí alma-cenados.

• Se recomienda definir un método privado para buscar un determinado nombre de modelo en elarray, y devuelva la posición donde se encuentra, o -1 en otro caso.

Finalmente, el programa principal realizará las siguientes acciones:

a) Creará un objeto concesionario,b) Añadirá los siguientes coches:

• Coche de ocasión, Seat-Marbella, precio 9000, descuento 20%.• Coche, Seat-Leon, precio 15000.• Coche de importación, Porsche-911, precio 39000, homologación 1000.

c) Clonará el concesionario actual en otro nuevo, y destruirá el antiguo.d) Calculará y mostrará el precio final de los tres coches anteriores.e) Seleccionará y mostrará el coche más barato.f ) Mostrará el contenido completo del concesionario.g) Finalmente, destruirá el concesionario.

Producirá la siguiente salida en pantalla:

Precio Seat-Marbella: 7200Precio Seat-Leon: 15000Precio Porsche-911: 40000Mas Barato: (Seat-Marbella, 7200){ (Seat-Marbella, 7200), (Seat-Leon, 15000), (Porsche-911, 40000) }

39

Page 40: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Práctica 9: La Clase Vector de la Biblioteca Estándar1. Defina e implemente la clase Hotel (dentro del espacio de nombres umalcc) que defina las siguientes estruc-

turas de datos y proporcione los siguientes métodos públicos para gestionar la ocupación de habitacionesy reservas de un hotel:

Estructura de Datos: La estructura que contendrá los datos de ocupación de las habitaciones se definirámediante un tipo vector de dos dimensiones, donde cada fila almacena los datos de cada planta del hotel,cada planta contiene las habitaciones de esa planta, y donde cada habitación se compone del nombre delcliente (cadena de caracteres) que se encuentra alojado.

Hotel

habitaciones0 1 2 3 4

0 nombre · · · · · · · · · · · ·1 · · · · · · · · · · · · · · ·2 · · · · · · · · · · · · · · ·

Métodos Públicos:

a) Hotel(⇓ n_plantas, ⇓ n_habs):Inicializará la estructura de datos Hotel a un estado vacío, es decir, sin habitaciones ocupadas, de talforma que el vector que representa las habitaciones del hotel se creará con tantas filas como indique elparámetro n_plantas, y tantos elementos por fila como indique el parámetro n_habs.

b) ~Hotel():Liberará y destruirá todos los recursos asociados a la estructura de datos Hotel.

c) Mostrar():Muestra en pantalla toda la información almacenada en las estructuras de datos del Hotel, en un formatoadecuadamente legible.

d) Alojar(⇓ nombre, ⇑ planta, ⇑ n_hab, ⇑ ok):Comprueba si hay habitaciones disponibles, en cuyo caso alojará adecuadamente a dicho cliente en algunahabitación que no esté ocupada. ok tomará el valor true, y planta y n_hab tomarán el valor de la plantay número de habitación donde se alojará el cliente.Cuando se aloja un determinado cliente en una habitación (planta y número de habitación), ésta pasaráa estar ocupada por dicho cliente, almacenando su nombre.Si todas las habitaciones están ocupadas, ok tomará el valor false.

e) Desalojar(⇓ nombre, ⇑ ok):Busca el cliente cuyo nombre se especifica como parámetro, y en caso de encontrarlo en una determinadahabitación, lo desalojará de ella borrando su nombre (a ""), y ok tomará el valor true. En otro caso, oktomará el valor false.

Notas:

a) ⇓ Especifica un parámetro de entrada y ⇑ especifica un parámetro de salida.b) El parámetro nombre es de tipo “cadena de caracteres”.c) El parámetro ok es de tipo “lógico” (“boolean”).d) Los parámetros planta y n_hab representan la planta y número de habitación donde se alojará el cliente

en caso de que la operación haya sido correcta, y se representan mediante números de tipo “entero”.

2. Diseñe un programa que utilice la clase Hotel definida anteriormente y permita gestionar las habitacionesde un hotel.

3. Añada de forma incremental los siguientes métodos públicos a la clase Hotel realizado anteriormente:

a) Anyadir_Planta(⇑ ok):Si el hotel tiene al menos una planta, entonces añade una nueva planta al hotel actual, acontinuación de las ya existentes, con tantas habitaciones como haya en la última planta, yok tomará el valor true. En otro caso, ok tomará el valor false. Estas nuevas habitacionesse crearán en estado disponible.

b) Eliminar_Planta(⇑ ok):Si el hotel tiene más de una planta, y la última planta tiene todas sus habitaciones en estadodisponible, entonces elimina la última planta del hotel y ok tomará el valor true. En otrocaso, ok tomará el valor false.

40

Page 41: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

c) Extender_Habitaciones(⇓ n_habs, ⇑ ok):Si el hotel tiene al menos una planta, y el numero de habitaciones de la primera planta esmenor que el valor del parámetro n_habs, entonces añade a cada planta tantas habitacionescomo sea necesario para que cada planta tenga el nuevo número de habitaciones especificadopor el valor del parámetro n_habs, y ok tomará el valor true. En otro caso, ok tomará elvalor false. Estas nuevas habitaciones se crearán en estado disponible.

4. Modifique el programa que utiliza la clase Hotel especificado anteriormente para que utilice los nuevosmétodos añadidos anteriormente.

41

Page 42: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Prácticas de Autoevaluación

Gestión de Factoría de AndroidesLa clase Pieza

Defina e implemente en el espacio de nombres umalcc la clase Pieza (en los ficheros pieza.hpp y pieza.cpp),que proporcione los métodos públicos especificados a continuación.

Estructura de datos interna de la claseLa estructura de datos interna de la clase Pieza almacena la información relativa a unadeterminada pieza, compuesta por su código de pieza (de tipo int), y su identificador(de tipo string). El código de la pieza hace referencia al tipo de pieza en concreto,según los códigos representados en la tabla lateral.

cod 2id C-123-4567

Código Descripción0 Cabeza1 Tronco2 Brazo-Izq3 Brazo-Dch4 Pierna-Izq5 Pierna-Dch

Métodos Públicos

~Pieza(); // Destructor

Destruye el objeto, liberando todos los recursos asociados al mismo.

Pieza(); // Constructor por defecto

Inicializa el código del objeto con valor -1 y el identificador con valor vacío ("").

Pieza(const int cod, const std::string& id);

Inicializa el objeto con los valores especificados en los parámetros. El primer parámetro especifica el códigode la pieza, y el segundo parámetro su identificador.

Tanto el constructor de copia como el operador de asignación serán generados por el compilador.

int obtener_codigo() const;

Devuelve el valor del atributo código del objeto actual.

std::string obtener_id() const;

Devuelve el valor del atributo identificador del objeto actual.

bool error() const;

Devuelve true si el valor del atributo código es inválido, o si el valor del atributo identificador es vacío(""). En otro caso, devuelve false.

void mostrar() const;

Muestra en pantalla, según el siguiente formato, la información almacenada en el estado interno del objeto.Si el objeto está en modo erróneo, añadirá la palabra ERROR al final de la línea. Por ejemplo:

2 C-123-4567 7 C-123-4567 ERROR

La clase Androide

Defina e implemente en el espacio de nombres umalcc la clase Androide (en los ficheros androide.hpp yandroide.cpp), que proporcione los métodos públicos especificados a continuación.

Estructura de datos interna de la claseLa estructura de datos interna de la clase Androide almacena la información relativa ala composición de un determinado androide, compuesta por su identificador (de tipostring), y de un array (piezas) de 6 cadenas de caracteres (string), de tal forma queel identificador de cada pieza que compone el androide se almacenará en el índice quese corresponde con el código de la pieza. Por ejemplo, el identificador de la cabeza sealmacenará en la posición 0 del array, el tronco en la posición 1, el brazo izquierdo enla posición 2, y así sucesivamente, según la tabla de códigos especificada en la clasePieza.

id B-987-6734piezas

0 A-251-42451 C-251-96822 C-123-45673 C-123-25634 A-762-82305 C-762-8274

42

Page 43: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Métodos Públicos

~Androide(); // Destructor

Destruye el objeto, liberando todos los recursos asociados al mismo.

Androide(); // Constructor por defecto

Inicializa el identificador del objeto y de las piezas que lo componen con valor vacío ("").

Androide(const std::string& i);

Inicializa el identificador del objeto con el valor especificado en el parámetro, y el identificador de laspiezas que lo componen con valor vacío ("").

Tanto el constructor de copia como el operador de asignación serán generados por el compilador.

std::string obtener_id() const;

Devuelve el valor del atributo identificador del objeto actual.

void anyadir_pieza(const Pieza& p, bool& ok);

Añade la pieza especificada a los componentes del objeto actual en la posición adecuada (indicada por elcódigo de la pieza) y devuelve true en ok si la operación se realiza correctamente. La operación fallará,y devolverá false en ok, si el objeto actual es erróneo, o si la pieza a añadir es errónea, o si ya existe esecomponente en el objeto (el identificador almacenado en la posición indicada por el código no es vacío).

void retirar_pieza(int codigo, Pieza& p);

Retira del objeto actual la pieza cuyo código se especifica como parámetro, y devuelve su valor adecua-damente (código e identificador) en el parámetro de salida p. Si el código es erróneo, o el componenteespecificado no existe, o el objeto actual es erróneo, entonces devolverá una pieza vacía (en modo erróneo).

bool error() const;

Devuelve true si el valor del atributo identificador es vacío (""). En otro caso, devuelve false.

void mostrar() const;

Muestra en pantalla, según el siguiente formato, la información almacenada en el estado interno del objeto.Si el objeto está en modo erróneo, añadirá la palabra ERROR al final de la primera línea.

Androide B-987-67340 A-251-42451 C-251-96822 C-123-45673 C-123-25634 A-762-82305 C-762-8274

Androide ERROR012345

La clase Factoría

Defina e implemente en el espacio de nombres umalcc la clase Factoria (en los ficheros factoria.hpp yfactoria.cpp), que proporcione los métodos públicos especificados a continuación.

Estructura de datos interna de la clase

La estructura de datos interna de la clase Factoria almacena información para facilitar el ensamblaje deandroides utilizando las piezas adecuadas, para ello utiliza las clases Pieza y Androide definidas anteriormente.Así, la clase Factoria contiene un primer atributo, androides, que almacena los androides ya ensamblados enun vector1 de elementos de tipo Androide. Además, tiene un segundo atributo, piezas, que es un puntero anodos que se encuentran organizados como una lista enlazada, donde cada nodo de la lista enlazada contieneun objeto de la clase Pieza. Por ejemplo:

1Si el alumno lo desea, obteniendo menor puntuación, podrá utilizar una estructura de lista de máximo 10 elementos en lugardel tipo vector.

43

Page 44: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Factoria

androides

B-987-6734

A-251-4245C-251-9682C-123-4567C-123-2563A-762-8230C-762-8274

A-765-9823

A-232-8822A-232-8923A-213-1233A-213-9232A-621-9234A-621-9213

D-987-6734

A-251-2312C-213-9213F-912-2139F-912-2138F-912-8923F-912-8213

piezas• - • -

3F-732-2193

• -0

A-823-9332

• -1

A-824-8455

/

2A-213-2372

Métodos Públicos

~Factoria(); // Destructor

Destruye el objeto, liberando todos los recursos asociados al mismo.

Factoria(); // Constructor por defecto

Inicializa el estado interno del objeto con el vector de androides vacío yla lista de piezas vacía.

Factoria(const Factoria& obj); // Constructor de copia

Crea un nuevo objeto copiando (duplicando) el estado del objeto obj recibido como parámetro.

Nótese que NO se debe implementar el operador de asignación.

void mostrar() const;

Androide B-987-67340 A-251-42451 C-251-96822 C-123-45673 C-123-25634 A-762-82305 C-762-8274

Androide A-765-98230 A-232-88221 A-232-89232 A-213-12333 A-213-92324 A-621-92345 A-621-9213

Androide D-987-67340 A-251-23121 C-213-92132 F-912-21393 F-912-21384 F-912-89235 F-912-8213

Piezas3 F-732-21930 A-823-93321 A-824-84552 A-213-2372

Muestra en pantalla, según el formato mostrado en la figura superior, la información del estado internodel objeto (el vector de androides desde el principio, y la lista de piezas según su orden secuencial).

void anyadir_pieza(const int cod, const std::string& id, bool& ok);

Si NO existe en la lista de piezas ninguna pieza con identificador igual al especificado por el parámetroid, entonces crea una pieza con los parámetros especificados, y si la pieza creada NO es errónea, entoncesla inserta al final en la lista de piezas, y asigna true al parámetro ok. En otro caso, asigna false alparámetro ok.

void eliminar_pieza(const std::string& id, bool& ok);

En caso de que exista, elimina de la lista de piezas aquella pieza cuyo identificador sea igual al valor delparámetro id, y asigna true al parámetro ok. En otro caso, asigna false al parámetro ok.

void ensamblar_androide(const std::string& id, bool& ok);

Si NO existe en el sistema ningún androide con identificador igual al especificado por el parámetro id,entonces crea un androide con el identificador especificado, y si el androide creadoNO es erróneo, entonces:

1. Comprueba si hay piezas suficientes de los códigos adecuados para ensamblar un androide.

2. En caso afirmativo del paso anterior:

a) Retira las piezas de los códigos adecuados de la lista de piezas y las añade al androide hastacompletarlo.

b) Inserta el androide ensamblado al final en el vector de androides.c) Finalmente asigna true al parámetro ok.

En el caso de que no se haya podido realizar la operación correctamente, entonces asigna false al pará-metro ok.

void desmontar_androide(const std::string& id, bool& ok);

En caso de que exista, retira las piezas que componen el androide cuyo identificador sea igual al valor delparámetro id, añadiéndolas a la lista de piezas, también elimina del vector de androides aquel androidecuyo identificador sea igual al valor del parámetro id, y asigna true al parámetro ok. En otro caso, asignafalse al parámetro ok.

44

Page 45: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

El programa Principal

Así mismo, el alumno puede utilizar el programa principal que se proporciona (en el fichero main_androides.cppque debe descargarse desde el Campus Virtual) para poder comprobar adecuadamente la corrección de los mé-todos de las clases.

Además, se proporciona un fichero (salida_androides.txt) con la salida esperada para el programa prin-cipal que se suministra, de tal forma que el alumno pueda comprobar su corrección.

45

Page 46: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

Gestión de Tareas PeriódicasLa clase Tarea

Defina e implemente en el espacio de nombres umalcc la clase Tarea (en los ficheros tarea.hpp y tarea.cpp),que proporcione los métodos públicos especificados a continuación.

Estructura de datos interna de la claseLa estructura de datos interna de la clase Tarea almacena la información relativa a unadeterminada tarea periódica del sistema, tal como su identificador (de tipo string), elcódigo de la tarea (de tipo int), el periodo de ejecución (en segundos) de la tarea (detipo int), el límite de tiempo (en segundos) que indica el tiempo en el que finalizarála ejecución de la tarea (de tipo int), la prioridad de la tarea, siendo un número enteromayor o igual a cero, donde el valor cero indica la mayor prioridad (de tipo int), el tiempopróximo de ejecución (en segundos) que indica cuando será ejecutada próximamente latarea (de tipo int) y un determinado valor que representa un número entero (de tipoint).

Tarea

identificadorcódigoperiodolímite

prioridadpróximo

valor

Tarea-0115300102

Métodos Públicos

~Tarea(); // Destructor

Destruye el objeto, liberando todos los recursos asociados al mismo.

Tarea(); // Constructor por defecto

Inicializa el objeto con identificador vacío (""), y con valor cero (0) el resto de atributos.

Tarea(const std::string& id, int cod, int per, int lim, int prio, int prox, int val);

Inicializa el objeto con los valores especificados en los parámetros. Los parámetros están especificados enel mismo orden que los atributos en la figura anterior.

// Tarea(const Tarea& obj); // Constructor de copia// Tarea& operator=(const Tarea& obj); // Operador de asignación

Tanto el constructor de copia como el operador de asignación serán generados por el compilador.

std::string obtener_id() const;

Devuelve el valor del atributo identificador del objeto actual.

int obtener_prioridad() const;

Devuelve el valor del atributo prioridad del objeto actual.

int obtener_proximo() const;

Devuelve el valor del atributo próximo del objeto actual.

bool esta_activa() const;

Devuelve true si el valor del atributo próximo es menor que el valor del atributo límite en el objetoactual. En otro caso, devuelve false.

bool error() const;

Devuelve true si el valor del atributo identificador es vacío (""), o si el valor del atributo código o el valordel atributo periodo es menor o igual a cero. En otro caso, devuelve false.

void mostrar_estado() const;

Muestra en pantalla, según el siguiente formato, la información almacenada en el estado interno del objeto.Además, si la tarea NO está activa, entonces también mostrará dos asteriscos (**) al final de la línea.Para el ejemplo de la figura anterior mostrará:

Tarea-01 1 5 30 0 10 2

void ejecutar(int tiempo_actual);

Si el valor del atributo próximo del objeto es igual al valor del parámetro tiempo_actual, entonces ejecutala tarea actual según lo especificado a continuación:

46

Page 47: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

1. Incrementa el valor del atributo próximo con el valor del atributo periodo.2. Si el valor del parámetro tiempo_actual es menor que el valor del atributo límite, entonces realiza

las siguientes acciones:a) Si el valor del atributo código de la tarea es uno (1), entonces eleva al cuadrado el valor del

atributo valor y almacena el resultado en el atributo valor.b) Si el valor del atributo código de la tarea es dos (2), entonces multiplica por dos el valor del

atributo valor y almacena el resultado en el atributo valor.c) Si el valor del atributo código de la tarea es tres (3), entonces multiplica por tres el valor del

atributo valor y almacena el resultado en el atributo valor.

La clase Planificador

Defina e implemente en el espacio de nombres umalcc la clase Planificador (en los ficheros planificador.hppy planificador.cpp), que proporcione los métodos públicos especificados a continuación.

Estructura de datos interna de la clase

La estructura de datos interna de la clase Planificador almacena información para facilitar la gestión yejecución de tareas periódicas del sistema, para ello utiliza la clase Tarea definida anteriormente. Así, la clasePlanificador contiene un atributo que almacena el valor del tiempo_actual de la ejecución en segundos (detipo int). Además, tiene un segundo atributo, tareas, que es un vector de punteros a nodos que se encuentranorganizados como listas enlazadas ordenadas, donde cada nodo de la lista enlazada contiene un objeto de laclase Tarea.

Cada tarea se encontrará en la lista enlazada que comienza en el elemento del vector cuyo índice es iguala la prioridad de la tarea, y se encontrará ordenada según el valor de su atributo próximo. Por ejemplo:

Planificador

tiempo_actual1

tareas0 • -1 /2 /3 /4 /5 /6 /7 • -

• -Tarea-07· · ·

prio: 0prox: 1

• -Tarea-03· · ·

prio: 0prox: 1

/Tarea-09· · ·

prio: 0prox: 3

• -Tarea-05· · ·

prio: 7prox: 1

/Tarea-02· · ·

prio: 7prox: 4

Métodos Públicos

~Planificador(); // Destructor

Destruye el objeto, liberando todos los recursos asociados al mismo.

Planificador(); // Constructor por defecto

Inicializa el estado interno del objeto con el tiempo_actual a cero (0), y el vector de tareas vacío.

Planificador(const Planificador& obj); // Constructor de copia

Crea un nuevo objeto copiando (duplicando) el estado del objeto obj recibido como parámetro.Nótese que NO se debe implementar el operador de asignación.

void mostrar() const;

Muestra en pantalla, según el siguiente formato, la información del estado interno del objeto (el vector detareas desde el principio, y las listas de tareas según su ordenación). Si alguna lista de tareas está vacía,entonces mostrará el mensaje Vacio. Para el ejemplo de la figura anterior, mostrará:

Tiempo actual: 1Tarea-07 2 7 30 0 1 32Tarea-03 1 3 30 0 1 2Tarea-09 1 5 2 0 3 8 **VacioVacioVacioVacioVacioVacioTarea-05 1 4 30 7 1 4Tarea-02 3 3 2 7 4 2 **

47

Page 48: Programación IIvicente/docencia/docencia/mp_ejercicios... · 2018-06-04 · 6.Escriba un programa que tome como entrada el fichero del ejercicio anterior y una condición sobre

void anyadir_tarea(const std::string& id, int cod, int per, int lim,int prio, int prox, int val, bool& ok);

Si el valor del parámetro prio es mayor o igual a cero, y el valor del parámetro prox es mayor o igual al valordel atributo tiempo_actual, y NO existe en el sistema una tarea con identificador igual al especificadopor el parámetro id, entonces crea una tarea con los parámetros especificados, y si la tarea creada NO eserrónea, entonces la inserta de forma ordenada (según el valor del parámetro prox ) en la lista de tareascuyo índice es igual al valor del parámetro prio, y asigna true al parámetro ok. En otro caso, asigna falseal parámetro ok.Nota: debe asegurarse de que la lista de tareas con la prioridad especificada ha sido creada adecuadamenteen el vector de tareas.

void eliminar_tarea(const std::string& id, bool& ok);

En caso de que exista, elimina del sistema aquella tarea cuyo identificador sea igual al valor del parámetroid, y asigna true al parámetro ok. En otro caso, asigna false al parámetro ok.Nota: en caso de que los últimos elementos del vector de tareas sean listas vacías, estos elementos deberánser eliminados, de tal forma que el último elemento del vector, si existe, debe ser una lista NO vacía.

bool hay_tareas_activas() const;

Devuelve true si hay tareas activas (véase el método esta_activa() de la clase Tarea) en el sistema, yfalse en otro caso.

void eliminar_tareas_terminadas();

Elimina del sistema todas aquellas tareas que NO están activas (véase el método esta_activa() de laclase Tarea).Nota: en caso de que los últimos elementos del vector de tareas sean listas vacías, estos elementos deberánser eliminados, de tal forma que el último elemento del vector, si existe, debe ser una lista NO vacía.

void ejecutar_ciclo();

Ejecuta las tareas del sistema que están preparadas, según el orden de prioridad del vector de tareas (elíndice cero es el más prioritario), y el orden del tiempo próximo de ejecución de cada tarea. Al finalizar,deberá incrementar en uno (1) el valor del atributo tiempo_actual del objeto.

Así, para cada tarea cuyo tiempo próximo de ejecución es igual al valor del atributo tiempo_actual, seextrae la tarea del principio de la lista enlazada correspondiente, entonces se ejecuta la tarea (invocandoal método ejecutar() de la clase Tarea), y se vuelve a insertar de forma ordenada (según su nuevo tiempopróximo de ejecución) en la lista correspondiente según su prioridad.

El programa Principal

Así mismo, el alumno puede utilizar el programa principal que se proporciona (en el fichero main_tareas.cppque debe descargarse desde el Campus Virtual) para poder comprobar adecuadamente la corrección de losmétodos de las clases.

Además, se proporciona un fichero (salida_tareas.txt) con la salida esperada para el programa principalque se suministra, de tal forma que el alumno pueda comprobar su corrección.

48