Actualizado el 21 de Marzo del 2018 (Publicado el 11 de Marzo del 2018)
625 visualizaciones desde el 11 de Marzo del 2018
1,2 MB
239 paginas
Creado hace 11a (26/06/2012)
Programaci´on II
Relaci´on de Ejercicios
y Soluciones
Sonido e Imagen
UNIVERSIDAD DE M ´ALAGA
Dpto. Lenguajes y CC. Computaci´on
E.T.S.I. Telecomunicaci´on
´Indice
Tema 1: Almacenamiento en Memoria Secundaria. Ficheros
Tema 2: Tipos Abstractos de Datos
Tema 2.1: Programacion Modular . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tema 2.2: Tipos Abstractos de Datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tema 2.3: Tipos Abstractos de Datos Gen´ericos . . . . . . . . . . . . . . . . . . . . . . . .
Tema 3: Gesti´on de Memoria Din´amica
Tema 3.1: Listas Enlazadas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Tema 3.2: Abstracci´on en la Gesti´on de Memoria Din´amica . . . . . . . . . . . . . . . . .
2
15
15
24
49
74
74
93
Tema 3.3: Genericidad en la Gesti´on de Memoria Din´amica . . . . . . . . . . . . . . . . . 136
Tema 4: Colecciones
Pr´acticas de Laboratorio
147
162
Pr´actica 1: Almacenamiento Persistente de Datos . . . . . . . . . . . . . . . . . . . . . . . 162
Pr´actica 2: Tipos Abstractos de Datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
Pr´actica 3: Tipos Abstractos de Datos Gen´ericos . . . . . . . . . . . . . . . . . . . . . . . 181
Pr´actica 4: Gesti´on de Memoria Din´amica . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
Pr´actica 5: Abstracci´on en la Gesti´on de Memoria Din´amica . . . . . . . . . . . . . . . . . 200
Pr´actica 6: Biblioteca Est´andar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
Problemas de Examen
214
Examen 1: Gesti´on de Agencia de Viajes . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214
Examen 2: Juego de Ajedrez
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
Examen 3: Gesti´on de Hotel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
Este obra est´a bajo una licencia Reconocimiento-NoComercial-CompartirIgual 3.0 Unported de
Creative Commons: No se permite un uso comercial de la obra original ni de las posibles obras derivadas,
la distribuci´on de las cuales se debe hacer con una licencia igual a la que regula la obra original. Para
ver una copia de esta licencia, visite http://creativecommons.org/licenses/by-nc-sa/3.0/deed.es ES o
envie una carta a Creative Commons, 171 Second Street, Suite 300, San Francisco, California 94105, USA.
1
Nota: en la soluci´on a los ejercicios, se ha utilizado el tipo array de TR1, que ha sido incorporado a la biblio-
teca de C++ en el est´andar de 2011. Si su biblioteca est´andar no contiene la definici´on del tipo array, puede
descargarla desde la siguiente direcci´on: http://www.lcc.uma.es/%7Evicente/docencia/cpplibs/array_tr1.zip
Tema 1: Almacenamiento en Memoria Secundaria. Ficheros
1. Escribir un programa que cuente el n´umero de letras min´usculas, de letras may´usculas y de d´ıgitos de un
fichero.
#include <iostream>
#include <fstream>
using namespace std;
struct Estad {
unsigned may;
unsigned min;
unsigned dig;
};
Soluci´on
// inicializa cuenta de estadisticas
void inic(Estad& sts)
{
sts.may = 0;
sts.min = 0;
sts.dig = 0;
}
// muestra las estadisticas
void escribir(const Estad& sts)
{
cout << "Mayusculas: " << sts.may << endl;
cout << "Minusculas: " << sts.min << endl;
cout << "Digitos: " << sts.dig << endl;
}
inline bool es_mayuscula(char c)
{
return (c >= ’A’ && c <= ’Z’);
}
inline bool es_minuscula(char c)
{
return (c >= ’a’ && c <= ’z’);
}
inline bool es_digito(char c)
{
return (c >= ’0’ && c <= ’9’);
}
void procesar(char c, Estad& sts)
{
if (es_mayuscula(c)) {
++sts.may;
} else if (es_minuscula(c)) {
++sts.min;
} else if (es_digito(c)) {
++sts.dig;
}
}
void estadisticas(const string& nombre, bool& ok, Estad& sts)
{
ifstream fich;
fich.open(nombre.c_str());
if (fich.fail()) {
ok = false;
} else {
inic(sts);
char c;
fich.get(c);
while (! fich.fail()) {
procesar(c, sts);
fich.get(c);
}
ok = fich.eof();
fich.close();
}
2
}
int main()
{
bool ok;
Estad sts;
cout << "Introduzca el nombre del fichero: ";
string nombre;
cin >> nombre;
estadisticas(nombre, ok, sts);
if (ok) {
escribir(sts);
} else {
cout << "Error al procesar el fichero" << endl;
}
}
2. Escribir un programa con la opci´on de encriptar y de desencriptar un fichero de texto, dependiendo de la
extensi´on del fichero de entrada. La encriptaci´on (codificaci´on) consiste en que dado un fichero de texto
de entrada (extensi´on txt) genere otro fichero de salida encriptado (extensi´on cod). Esta codificaci´on
consiste 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´on de desencriptado consiste en leer un fichero codificado (extensi´on cod) y recuperar
la informaci´on original en un fichero de texto (extensi´on txt).
Soluci´on
#include <iostream>
#include <fstream>
using namespace std;
const unsigned DESPL = 3;
enum Operacion {
CIFRAR, DESCIFRAR, ERROR
};
// cifrado rotacional (DESPL) de letra
char cifrar(char c)
{
if (c >= ’a’ && c <= ’z’) {
c = char(c + DESPL);
if (c > ’z’) {
c = char(’a’ + c - ’z’ - 1);
}
} else if (c >= ’A’ && c <= ’Z’) {
c = char(c + DESPL);
if (c > ’Z’) {
c = char(’A’ + c - ’Z’ - 1);
}
}
return c;
}
// descifrado rotacional (DESPL) de letra
char descifrar(char c)
{
if (c >= ’a’ && c <= ’z’) {
c = char(c - DESPL);
if (c < ’a’) {
c = char(’z’ + c - ’a’ + 1);
}
} else if (c >= ’A’ && c <= ’Z’) {
c = char(c - DESPL);
if (c < ’A’) {
c = char(’Z’ + c - ’A’ + 1);
}
}
return c;
}
// transforma una letra segun el codigo de operacion
char transformar(char c, Operacion op)
{
char res;
if (op == CIFRAR) {
3
res = cifrar(c);
} else {
res = descifrar(c);
}
return res;
}
// trasnforma el fichero de entrada y lo escribe en el fichero de salida
void transformar_fichero(const string& entrada, const string& salida,
Operacion op, bool& ok)
{
ifstream f_ent;
f_ent.open(entrada.c_str());
if (f_ent.fail()) {
ok = false;
} else {
ofstream f_sal;
f_sal.open(salida.c_str());
if (f_sal.fail()) {
ok = false;
} else {
char ch;
f_ent.get(ch);
while (! f_ent.fail() && ! f_sal.fail()) {
f_sal.put(transformar(ch, op));
f_ent.get(ch);
}
ok = (f_ent.eof() && ! f_sal.fail());
f_sal.close();
}
f_ent.close();
}
}
// busca un caracter e una cadena
unsigned buscar(const string& nombre, char c)
{
unsigned i = 0;
while ((i < nombre.size())&&(c != nombre[i])) {
++i;
}
return i;
}
// devuelve la extension del nombre de fichero
string extension(const string& nombre)
{
string res = "";
unsigned i = buscar(nombre, ’.’);
if (i < nombre.size()) {
res = nombre.substr(i+1, nombre.size()-(i+1));
}
return res;
}
// calcula la operacion a realizar a partir de las extensiones de los
// ficheros de entrada y salida
Operacion codigo_op(const string& entrada, const string& salida)
{
Operacion res;
if ((extension(entrada)=="txt")&&(extension(salida)=="cod")) {
res = CIFRAR;
} else if ((extension(entrada)=="cod")&&(extension(salida)=="txt")) {
res = DESCIFRAR;
} else {
res = ERROR;
}
return res;
}
int main()
{
bool ok;
cout << "Introduzca el nombre del fichero de entrada: ";
4
string nombre_ent;
cin >> nombre_ent;
cout << "Introduzca el nombre del fichero de salida: ";
string nombre_sal;
cin >> nombre_sal;
Operacion op = codigo_op(nombre_ent, nombre_sal);
if (op != ERROR) {
transformar_fichero(nombre_ent, nombre_sal, op, ok);
if (ok) {
cout << "Procesamiento correcto" << endl;
} else {
cout << "Error al procesar el fichero" << endl;
}
} else {
cout << "Error: extensiones erroneas" << endl;
}
}
3. Escribir un programa para procesar informaci´on sobre los clientes de una agencia matrimonial. El programa
debe crear un fichero de texto (cuyo nombre se leer´a por teclado) en el que se guarde la informaci´on de
un n´umero indeterminado de personas. La informaci´on que se guardar´a por cada persona ser´a:
Nombre: Cadena de caracteres.
Edad
G´enero
Arte
Deporte
Libros
M´usica
int.
char (M/F).
char (S/N).
char (S/N).
char (S/N).
char (S/N).
La informaci´on correspondiente a cada persona se leer´a del teclado. El proceso finalizar´a cuando se teclee
un campo Nombre que est´e vac´ıo.
Soluci´on
#include <iostream>
#include <fstream>
#include <string>
#include <tr1/array>
using namespace std;
using namespace std::tr1;
enum Genero {
FEMENINO, MASCULINO
};
const unsigned NAFICCIONES = 4;
typedef array<string, NAFICCIONES> StrAficciones;
const StrAficciones AFICCIONES = {{
"Arte", "Deporte", "Libros", "Musica"
}};
typedef array<bool, NAFICCIONES> Aficciones;
struct Persona {
string nombre;
unsigned edad;
Genero gen;
Aficciones af;
};
//---------------------------------
// convierte una letra a mayusculas
inline char mayuscula(char c)
{
if (c >= ’a’ && c <= ’z’) {
c = char(c - ’a’ + ’A’);
}
return c;
}
//------------------------------------------------------------------
//-- Leer de Teclado -----------------------------------------------
//------------------------------------------------------------------
5
// leer una opcion (S/N) a bool
inline void leer(bool& a)
{
char c;
cin >> c;
a = (mayuscula(c) == ’S’);
}
// leer el genero (M/F) a tipo enumerado
inline void leer(Genero& g)
{
char c;
cin >> c;
if (mayuscula(c) == ’M’) {
g = MASCULINO;
} else {
g = FEMENINO;
}
}
// leer aficciones
void leer(Aficciones& af)
{
for (unsigned i = 0; i < af.size(); ++i) {
cout << AFICCIONES[i] << " (S/N): ";
leer(af[i]);
}
}
// leer datos de persona
void leer(Persona& p)
{
cout << "Nombre: ";
getline(cin, p.nombre);
if (p.nombre.size() > 0) {
cout << "Edad: ";
cin >> p.edad;
cout << "Genero (M/F): ";
leer(p.gen);
leer(p.af);
cin.ignore(1000, ’\n’);
}
}
//------------------------------------------------------------------
//-- Escribir a Fichero --------------------------------------------
//------------------------------------------------------------------
// escribir una opcion (S/N) bool a fichero
inline void escribir
Comentarios de: Programación II - Relación de Ejercicios y Soluciones - Sonido e Imagen (0)
No hay comentarios