Sunteți pe pagina 1din 10

EXAMEN FINAL DE TACCII

4 INGENIERIA INFORMTICA, UAM, 31-ENERO2006



Problema 1) NOTAS: i) Se recomienda leer todo el enunciado antes de comenzar a
resolver este problema.
ii) El apartado c) es opcional. Las restantes partes del examen suman 10 puntos.
a) (1,5 puntos) Se desea desarrollar un programa en C++que permita colocar tems
rectangulares de tamaos diversos en un contenedor formando hileras. La longitud
mxima de las hileras es fija y los tems se aaden colocndolos al final de la ltima
hilera hasta que no caben en ella, momento en que se comienza una hilera nueva
(para fijar ideas, el contenedor podra ser esta hoja de papel, los tems podran ser
las palabras que aparecen en este prrafo y las hileras las lneas que lo forman).
Se pide un programa que incluya la estructura de un conjunto de clases que permitan
la funcionalidad indicada y la definicin de un mtodo que aade un item al
contenedor, colocndolo al final de la ltima hilera o, si no hay espacio, al comienzo
de la siguiente. Las hileras tendrn una altura variable para ajustarse a la altura de
los itms que contienen. Entre cada dos hileras y entre cada dos tems consecutivos
no se dejar ningn espacio. Los tems contenidos en una hilera tendrn la parte ms
prxima a la hilera anterior pegada a la misma. La altura de cada hilera ser la
mayor de las alturas de los tems que contiene.
b) (1,5 puntos) Se desea utilizar el programa anterior (adaptndolo o extendindolo)
para programar un visualizador de documentos de texto basado en MFC de acuerdo
con las siguientes especificaciones:
I. Los documentos no tienen mrgenes superiores, inferiores, izquierdos ni
derechos. Los documentos estn formados por un slo prrafo en el que las
palabras se alinean a la izquierda, como en el primer prrafo de este enunciado.
Las longitudes que se mencionan a partir de aqu se miden en pixels.
II. Los prrafos estn formados por palabras. Las palabras corresponden a cadenas
de caracteres, implementadas mediante la clase CString de MFC y se dibujan
mediante el mtodo CDC::TextOut(int x, int y, CString contenido), en el que los
argumentos x e y denotan la posicin del vrtice ms prximo al comienzo del
documento donde se va a escribir la cadena de caracteres. Las dimensiones
(altura y anchura en pixels) de una cadena de caracteres al dibujarla en la
pantalla se obtienen mediante el mtodo CDC::GetTextExtent(CString), que
devuelve una estructura (struct) de tipo CSize con atributos cx y cy que son de
tipo int. (Nota: Se puede tambin utilizar la subclase CPaintDC de CDC en lugar
de esta ltima). Las palabras no estn separadas por ningn espacio (se puede
considerar que contienen los espacios en blanco necesarios como caracteres).
Se pide un programa que incluya la estructura de un conjunto de clases que permitan
la funcionalidad indicada y la definicin de un mtodo que dibuja el documento.
c) (opcional, 1,5 puntos) Se pide un programa semejante al del apartado b) anterior
(conjunto de clases y mtodo de dibujado) que permita visualizar documentos cuyo
contenido est formado por palabras y rectngulos. Para ello se supondr que en la
clase CDC se dispone de un mtodo DibujaRectangulo(int x, int y, int ancho, int
alto), en el que los argumentos x e y tienen un significado anlogo al que tienen en
el mtodo CDC::TextOut.
d) (2 puntos) Se pide un diagrama de clases que englobe en la mayor proporcin
posible los programas pedidos en los apartados anteriores.


Apartado 1.a)
t empl at e <cl ass I >
cl ass Cont enedor {
publ i c:
i nt ancho;
i nt al t o; / / Hast a l a l t i ma hi l er a compl et a
vect or <Hi l er a<I > *> hi l er as;
Cont enedor ( i nt ancho) ;
voi d anyadi r ( I *) ;
};

t empl at e <cl ass I >
cl ass Hi l er a {
publ i c:
Cont enedor <I > * cont ;
i nt pos; / / Al t ur a dent r o del cont enedor
i nt l ar go;
i nt al t o;
vect or <I *> i t ems;
Hi l er a( Cont enedor <I > *cont , i nt pos, I *i t em) ;
Bool anyadi r ( I *i t em) ;
};

/ / Par a ut i l i zar en l as cl ases Cont enedor e Hi l er a
t empl at e <cl ass C>
cl ass I t em{
publ i c:
i nt ancho;
i nt al t o;
i nt posx;
i nt posy;
C cont eni do;
};

t empl at e <cl ass I >
voi d Cont enedor <I >: : anyadi r ( I *i t em) {
i f ( hi l er as. si ze( ) == 0) {
hi l er as. push_back( new Hi l er a<I >( t hi s, 0, i t em) ) ;
r et ur n;
}
el se i f ( hi l er as[ hi l er as. si ze( ) - 1] - >anyadi r ( i t em) ) r et ur n;
el se {
al t o += hi l er as[ hi l er as. si ze( ) - 1] - >al t o;
hi l er as. push_back( new Hi l er a<I >( t hi s, al t o, i t em) ) ;
};
};

t empl at e <cl ass I >
bool Hi l er a<I >: : anyadi r ( I *i t em) {
i f ( l ar go + i t em- >ancho > cont - >ancho) r et ur n f al se;
i t em- >posx = l ar go;
i t em- >posy = cont - >al t o;
i t ems. push_back( i t em) ;
al t o = max( al t o, i t em- >al t o) ;
l ar go += i t em- >ancho;
r et ur n t r ue;
};



Apartado 1.b)
La versin que se muestra utiliza documentos y vistas; se puede hacer anlogamente sin
utilizar documentos, utilizando directamente una ventana marco sin vista, con una vista
de formulario o con un dilogo.

Mediante el wizard de Visual C++o por otro mtodo se definen de manera estndar las
clases CCont enedor MFCApp, CCont enedor MFCVi ew y CCont enedor MFCDoc.

A la clase CCont enedor MFCDoc se le aade un atributo vect or <CSt r i ng *>
cont eni do.

Se define una clase especfica de tems:

cl ass Cont enedor MFCI t em: I t em<CSt r i ng *> {
Cont enedor MFCI t em( CSt r i ng *st r , CDC *cdc) ;
};

El constructor de esta clase asigna las dimensiones al item utilizando el resultado del
mtodo CDC: : Get Text Ext ent ( CSt r i ng) :

Cont enedor MFCI t em( CSt r i ng *st r , CDC *dc) : I t em<CSt r i ng *>( st r ) {
CSi ze si ze = dc- >Get Text Ext ent ( *st r ) ;
ancho = si ze. cx;
al t o = si ze. cy;
};

La clase CCont enedor MFCVi ew se hace que sea subclase de
Cont enedor <Cont enedor MFCI t em> adems de serlo de CVi ew.

El mtodo CCont enedor MFCVi ew: : OnI ni t i al Updat e( ) asigna el ancho del
contenedor y construye iterativamente un Cont enedor MFCI t empor cada cadena del
contenido del documento, que aade al contenedor:

voi d CCont MFCVi ew: : OnI ni t i al Updat e( ) {
CVi ew: : OnI ni t i al Updat e( ) ;
Get Document ( ) - >cVi ew = t hi s;
LPRECT r ect = new t agRECT;
Get Cl i ent Rect ( r ect ) ;
ancho = r ect - >r i ght ;
f or ( i nt i = 0; i < Get Document ( ) - >cont eni do. si ze( ) ; i ++)
anyade( CCont enedor MFI t em( Get Document ( ) - >st r i ngs[ i ] ) ) ;
};

El mtodo de dibujado recorre las hileras y sus tems y dibuja en las posiciones
correspondientes sus contenidos:

voi d CCont enedor MFCVi ew: : OnDr aw( CDC* pDC) {
vect or <Hi l er a<I t em<St r i ng> > > hi l er as = get Document ( )
- >get Cont ai ner ( ) - >get Hi l er as( ) ;
f or ( i nt i = 0; i < hi l er as. si ze( ) ; i ++)
f or ( i nt j = 0; j < hi l er as[ i ] - >i t ems. si ze( ) ; j ++)
pDC- >Text Out ( hi l er as[ i ] - >i t ems[ j ] - >posx,
hi l er as[ i ] - >i t ems[ j ] - >posy, *hi l er as[ i ] - >i t ems[ j ] - >st r ) ;
};
Apartado 1.c)
Los cambios a realizar con respecto al apartado anterior son:

i) Definimos la clase I t emCont eni do y las subclases I t emCSt r i ng y I t emRect angul o:

cl ass I t emCont eni do {
};

cl ass I t emCSt r i ng : publ i c I t emCont eni do {
CSt r i ng st r ;
};

cl ass I t emRect angul o : publ i c I t emCont eni do {
i nt ancho;
i nt al t o;
};

El contenido del documento es un vector de punteros a I t emCont eni dos en lugar de
CSt r i ngs.

ii) Se crean dos subclases de la clase Cont enedor MFCI t em: Cont enedor MFCI t emSt r i ng
y Cont enedor MFCI t emRect , que son subclases respectivamente de
I t em<I t emCSt r i ng> y de I t em<I t emRect angul o>. Los constructores calculan las
dimensiones de los tems de distintas formas segn el caso (en un caso lo hacen como
en el apartado anterior, en otro a travs del rectngulo). Adems, la clase
Cont enedor MFCI t emtiene un mtodo virtual abstracto dr aw( CDC *) . Este mtodo se
define en cada subclase mediante los mtodos CDC: : Text Out y
CDC: : Di buj aRect angul o

iii) El mtodo de dibujado sustituye la llamada a pDC->TextOut por una llamada al
mtodo draw sobre los tems, con pDC como argumento:

voi d CCont enedor MFCVi ew: : OnDr aw( CDC* pDC) {
f or ( i nt i = 0; i < hi l er as. si ze( ) ; i ++)
f or ( i nt j = 0; j < hi l er as[ i ] - >i t ems. si ze( ) ; j ++)
hi l er as[ i ] - >i t ems[ j ] - >dr aw( pDC) ;
};


Apartado 1.d)

Diagrama de clases para el apartado a):



Diagrama de clases para el apartado b) (no se incluye la clase de la aplicacin ni la
cardinalidad de las relaciones):

Contenedor Hilera Item
1 1



El diagrama de clases para el apartado 1.c) es anlogo, excepto que la clase CString se
sustituye por la jerarqua formada por la clase I t emCont eni do y las subclases
I t emCSt r i ng y I t emRect angul o y anlogamente a la clase MFCItem se le aaden sus
dos subclases:




Contenedor Hilera Item
MFCItem ContMFCView
CView ItemCont
ContMFCDoc
CDocument
ItemCStr ItemRect
ContMFCIStr
ContMFCIRect
Contenedor Hilera Item
MFCItem ContMFCView
CView CString
ContMFCDoc
CDocument CDocument
Problema 2) (10 puntos) Completar el siguiente programa para que la salida sea la que
se indica:

Programa:
#i ncl ude <i ost r eam>
#i ncl ude <st r i ng>
usi ng namespace st d;
cl ass X {
publ i c:
voi d f ( ) {
cout << " Met odo f en cl ase X" << endl ;
}
};
cl ass Y {
publ i c:
voi d f ( ) {
cout << " Met odo f en cl ase Y" << endl ;
}
};
voi d mai n( i nt ar gc, char * ar gv[ ] )
{
X x; Y y;
x. f ( ) ; y. f ( ) ;
Z<X*> z1=&x; Z<Y*> z2=&y;
z1. f ( ) ; z2. f ( ) ;
}
Salida:
Met odo f en cl ase X
Met odo f en cl ase Y
Met odo f en cl ase X
Met odo f en cl ase Y

Solucin:

t empl at e <cl ass T>
cl ass Z {
publ i c:
T t ;
Z ( T t ) : t ( t ) {}
voi d f ( ) {
t - >f ( ) ;
}
};

Problema 3) (10 puntos) Escribir el cdigo de la clase A para que la salida sea la que se
indica, y que se verifique para cualesquiera valores de (x1,x2,x3):

Programa:
#i ncl ude <i ost r eam>
#i ncl ude <st r i ng>
usi ng namespace st d;
voi d mai n( i nt ar gc, char * ar gv[ ] )
{
i nt x1=5, x2=7, x3=8;
A a1( x1) , a2( x2) , a3( x3) ;
a1. val or ( ) ; a2. val or ( ) ; a3. val or ( ) ;
( a1+=a2) +=a3;
a1. val or ( ) ; a2. val or ( ) ; a3. val or ( ) ;
( x1+=x2) +=x3;
cout << " Val or es: " << x1 << " , " << x2
<< " , " << x3 << endl ;
}
Salida:
Val or : 5
Val or : 7
Val or : 8
Val or : 20
Val or : 7
Val or : 8
Val or es: 20, 7, 8

Solucin:

cl ass A {
publ i c:
i nt x;
A ( i nt x) : x( x) {}
voi d val or ( ) {
cout << " Val or : " << x << endl ;
}
A& oper at or += ( const A& a) {
x=x+a. x;
r et ur n *t hi s;
};
};

Problema 4) Suponer un sistema de realizacin de preguntas basadas en mens, en el
cual se formulan preguntas a un usuario y ste debe averiguar la respuesta correcta. Por
ejemplo, un men basado en nmeros para dos iteraciones sera del estilo siguiente
(ejemplo 1):

Pr egunt a: Capi t al de Fr anci a
1. Londr es
2. Roma
3. Par i s
4. Car acas
I nt r oduce el numer o cor r ect o
1
Respuest a i ncor r ect a
Pr egunt a: Capi t al de Fr anci a
1. Londr es
2. Roma
3. Par i s
4. Car acas
I nt r oduce el numer o cor r ect o
3
Respuest a cor r ect a

Cada men corresponde a un estilo distinto. Por ejemplo, otro caso sera el estilo
correspondiente a los mens basados en subcadenas, en donde el usuario debe responder
con las dos primeras letras de la opcin ante las mismas preguntas formuladas con este
otro tipo de men. En este caso el ejemplo (ejemplo 2) sera:

Pr egunt a: Capi t al de Fr anci a
- Londr es
- Roma
- Par i s
- Car acas
I nt r oduce l as dos pr i mer as l et r as de l a sol uci on
Pa
Respuest a cor r ect a
Pr egunt a: Capi t al de Fr anci a
- Londr es
- Roma
- Par i s
- Car acas
I nt r oduce l as dos pr i mer as l et r as de l a sol uci on
Ca
Respuest a i ncor r ect a

a) Implementar este sistema en C++ usando el patrn de Fbrica Abstracta
correspondiente al siguiente pseudocdigo para el mtodo main en el caso de un
men de nmeros, de modo que la ejecucin de este mtodo main sea el ejemplo 1
anterior

i nt mai n( i nt ar gc, char * ar gv[ ] )
{
<Cr eaci n de una f br i ca de mens de nmer os>
<Cr eaci n por l a f br i ca de un men >
<Cr ear l a pr egunt a " Capi t al de Fr anci a" par a el men>
<Cr ear l a opci n " Londr es" par a el men>
<Cr ear l a opci n " Roma" par a el men>
<Cr ear l a opci n " Par s" par a el men, como l a cor r ect a>
<Cr ear l a opci n " Car acas" par a el men>
<r epet i r dos veces>
<Ej ecut ar l a acci n pr egunt ar en el men>
<Ej ecut ar l a acci n r esponder en el men>
<f i n de r epet i ci n>
}

En la implementacin se debern utilizar las plantillas vector y string (para
representar colecciones de objetos y caracteres, respectivamente, sin utilizar arrays en
ningn caso), liberando la memoria dinmica utilizada. Adems se debe cumplir (que es
lo que permite este patrn de diseo) que para obtener el ejemplo 2 en lugar del
ejemplo 1 baste con cambiar la lnea de <Cr eaci n de una f br i ca de mens de nmer os>
por la correspondiente de cadenas <Cr eaci n de una f br i ca de mens de subcadenas>.

Solucin:

#i ncl ude <i ost r eam>
#i ncl ude <vect or >
#i ncl ude <st r i ng>
usi ng namespace st d;
cl ass Menu {
pr ot ect ed:
vect or <st r i ng> el ement os;
st r i ng sol uci on;
st r i ng pr egunt a;
st r i ng r espuest a;
publ i c:
voi d cr ear Pr egunt a( st r i ng s) {
pr egunt a=s;
}
voi d cr ear NuevaOpci on( st r i ng s, i nt cor r ect a=0) {
el ement os. push_back( s) ;
i f ( cor r ect a! =0)
sol uci on=s;
}
voi d r esponder ( ) {
i f ( r espuest a==sol uci on)
cout << " Respuest a cor r ect a" << endl ;
el se
cout << " Respuest a i ncor r ect a" << endl ;
}
vi r t ual voi d pr egunt ar ( ) = 0;
};
cl ass MenuDeNumer os : publ i c Menu {
publ i c:
vi r t ual voi d pr egunt ar ( ) {
cout << " Pr egunt a: " << pr egunt a << endl ;
f or ( i nt i =0; i <el ement os. si ze( ) ; i ++) {
cout << ( i +1) << " . " << el ement os[ i ] << endl ;
}
cout << " I nt r oduce el numer o cor r ect o" << endl ;
i nt j ;
ci n >> j ;
r espuest a=el ement os[ j - 1] ;
}
};
cl ass MenuDeSubcadenas : publ i c Menu{
publ i c:
vi r t ual voi d pr egunt ar ( ) {
cout << " Pr egunt a: " << pr egunt a << endl ;
f or ( i nt i =0; i <el ement os. si ze( ) ; i ++) {
cout << " - " << el ement os[ i ] << endl ;
}
cout << " I nt r oduce l as dos pr i mer as l et r as de l a sol uci on" << endl ;
st r i ng s;
ci n >> s;
f or ( i nt j =0; j <el ement os. si ze( ) ; j ++) {
i f ( el ement os[ j ] . subst r ( 0, 2) ==s)
r espuest a=el ement os[ j ] ;
}
}
};
cl ass Fabr i caDeMenus {
publ i c:
vi r t ual Menu* cr ear Menu ( ) = 0;
};
cl ass Fabr i caDeMenusDeNumer os : publ i c Fabr i caDeMenus {
publ i c:
vi r t ual Menu* cr ear Menu ( ) {
r et ur n new MenuDeNumer os( ) ;
}
};
cl ass Fabr i caDeMenusDeSubcadenas : publ i c Fabr i caDeMenus {
publ i c:
vi r t ual Menu* cr ear Menu ( ) {
r et ur n new MenuDeSubcadenas( ) ;
}
};
i nt mai n( i nt ar gc, char * ar gv[ ] )
{
Fabr i caDeMenus* f ;
/ / f =new Fabr i caDeMenusDeNumer os ( ) ;
f =new Fabr i caDeMenusDeSubcadenas ( ) ;
Menu* m=f - >cr ear Menu( ) ;
m- >cr ear Pr egunt a( " Capi t al de Fr anci a" ) ;
m- >cr ear NuevaOpci on( " Londr es" ) ;
m- >cr ear NuevaOpci on( " Roma" ) ;
m- >cr ear NuevaOpci on( " Par i s" , 1) ;
m- >cr ear NuevaOpci on( " Car acas" ) ;
f or ( i nt i =0; i <2; i ++) {
m- >pr egunt ar ( ) ;
m- >r esponder ( ) ;
}
del et e m;
del et e f ;
r et ur n 0;
}

b) Dibujar el diagrama de clases necesarias para los ejemplo 1 y ejemplo 2.

Solucin:

MenuDeNumeros
+preguntar(): void
Menu
#elementos: vector<string>
#solucion: string
#pregunta: string
#respuesta
+crearPregunta(s:string): void
+crearNuevaOpcion(string,correcta:int): void
+responder(): void
+preguntar()
FabricaDeMenus
+crearMenu(): Menu
FabricaDeMenusDeSubcadenas
+crearMenu(): Menu
MenuDeSubcadenas
+preguntar(): void
FabricaDeMenusDeNumeros
+crearMenu(): Menu


c) Dibujar el diagrama de secuencia correspondiente al ejemplo 1

una
FabricaDeMenusDe Numeros
un
MenuDeNumeros
un
Usuario
crearMenu
new
crearPregunta
* crearNuevaOpcion
preguntar
responder
new

S-ar putea să vă placă și