Está en la página 1de 31

7.

Diseo de Algoritmos
Como ya hemos mencionado, el principio bsico del diseo descendente es tratar de
resolver un problema mediante la resolucin de problemas ms simples. En este captulo
ahondaremos en el diseo de algoritmos iterativos.
En la seccin 7. presentamos estrategias de solucin de problemas basadas en el diseo
descendente. !resentaremos en la seccin 7." es#uemas de algoritmos bsicos de
tratamiento secuencial.
Como vimos en la seccin $.", el diseo descendente tambi%n se denomina tcnica de
refinamiento sucesivo. &asta el momento hemos aplicado el diseo descendente slo para
re'inar acciones abstractas en t%rminos de acciones cada ve( menos abstractas, es decir, #ue
se acercan cada ve( ms a las instrucciones propias de nuestro lengua)e de programacin.
*in embargo, cuando hacemos un primer algoritmo para resolver un problema, las acciones
describen realmente la interaccin de los ob)etos involucrados en el enunciado del
problema. !or lo tanto no basta con re'inar las acciones entre ob)etos sino #ue es preciso
re'inar +o representar, los ob)etos abstractos en t%rminos de ob)etos ms concretos. Con
'recuencia, los ob)etos involucrados en el enunciado del problema no son directamente
representables en lengua)es de programacin convencionales +por e)emplo, los con)untos,-
de all la necesidad de re'inar datos. .a representacin de ob)etos abstractos en t%rminos de
ob)etos concretos lo llamamos refinamiento de datos, y presentaremos una metodologa a
seguir para llevar a cabo tal representacin.
7.1. Diseo Descendente
.a metodologa de diseo descendente de programas consiste en/
, 0e'inir una solucin de un problema en t%rminos de la composicin de soluciones
de problemas #ue a priori son ms sencillos de resolver, o de es#uemas de solucin
ya conocidos.
", .a primera solucin del problema corresponder a una composicin de acciones
sobre los ob)etos al ms alto nivel de abstraccin, es decir, a los involucrados en la
especi'icacin del problema.
$, 1plicar re'inamiento sucesivo, el cual consiste en re'inar tanto las acciones como
los datos hasta conseguir #ue el algoritmo inicial se convierta en un programa.
En esta seccin ahondaremos en la prctica del diseo descendente, tanto en re'inamiento
de acciones como de datos. &asta el momento hemos aplicado el diseo descendente slo
para re'inar acciones abstractas en t%rminos de acciones cada ve( menos abstractas, es
decir, #ue se acercan cada ve( ms a las instrucciones propias de nuestro lengua)e de
programacin. *in embargo, cuando hacemos un primer algoritmo para resolver un
problema, las acciones describen realmente la interaccin de los ob)etos involucrados en el
enunciado del problema. !or lo tanto no basta con re'inar las acciones entre ob)etos sino
#ue es preciso re'inar +o representar, los ob)etos abstractos en t%rminos de ob)etos ms
concretos, a esto 2ltimo es a lo #ue llamamos refinamiento de datos. En los e)emplos de
$
diseo descendente vistos hasta ahora, no 'ue necesario re'inar los datos pues estos
correspondan a tipos no estructurados, como los n2meros enteros, los booleanos, etc.,
considerados tipos bsicos de nuestro pseudolengua)e #ue no hace 'alta re'inar.
El principio bsico del diseo descendente es se debe programar hacia un lengua)e de
programacin y no en el lengua)e de programacin, lo #ue signi'ica partir de algoritmos en
t%rminos de los ob)etos involucrados en la especi'icacin original del problema e ir
re'inndolos hasta obtener un programa en el lengua)e de programacin #ue hayamos
escogido. 3na ve( #ue un primer algoritmo correcto es encontrado, podemos cambiar la
representacin de los ob)etos por otros para me)orar, por e)emplo, la e'iciencia +en el
Captulo 4 hablaremos de e'iciencia, y5o implementarlos en el lengua)e de programacin.
Cada ob)eto involucrado en la especi'icacin de un problema posee una estructura y
propiedades #ue lo caracteri(a. Esta estructura y propiedades de'inen la clase o el tipo del
objeto. 6as concretamente, una clase de ob)etos se de'ine por un con)unto de valores y un
comportamiento #ue viene e7presado por operaciones sobre ese con)unto de valores- por
e)emplo, el tipo n2mero entero tiene como con)unto de valores 8..., 9, :, , ", $, ...; y
como operaciones la suma, la resta, la multiplicacin, etc. El tipo secuencia de caracteres
tiene como con)unto de valores a las 'unciones de <:..n, en los caracteres, cual#uiera sea el
n2mero natural n, y algunas operaciones son obtener el primero de la secuencia, insertar un
elemento en una posicin dada de una secuencia, etc.
En un lengua)e de programacin moderno, como =1>1, #ue permite definir clases de
objetos, el re'inamiento de datos se e'ect2a construyendo una unidad de programa aparte,
llamada igualmente clase, #ue contiene segmentos de programa #ue implementan por una
parte la representacin de los ob)etos en t%rminos de las estructuras de datos #ue o'rece el
lengua)e y por otra parte, las operaciones de la clase. 0ecimos #ue =1>1 permite
encapsular la implementacin de tipos abstractos de datos. El encapsulamiento de datos
conlleva al ocultamiento de datos, es decir, el programador #ue slo desea manipular
ob)etos de un determinado tipo de datos no tiene por #u% preocuparse por cmo se
representa ese tipo en 'uncin de tipos concretos- lo #ue realmente le interesa es poder
operar con ob)etos de ese tipo, y por lo tanto la implementacin puede permanecer oculta al
programador, permiti%ndole as no involucrarse con los detalles de implementacin del tipo.
7.1.1. Tratar de resolver un problema en trminos de problemas ms
simples
El t%rmino ms simple puede signi'icar di'erentes cosas seg2n el conte7to. 3n problema
puede ser ms simple debido a #ue algunas de sus restricciones han sido omitidas
+resultando en una generali(acin del problema,. El problema puede ser ms simple por#ue,
al contrario, le hemos agregado restricciones. Cual#uiera sea el caso, la estrategia de
resolver un problema en t%rminos de problemas ms simples consiste entonces primero #ue
nada en tratar de identi'icar y resolver casos mas simples del mismo problema y tratar de
resolver el problema original utili(ando la solucin de los casos ms simples
E)emplo/
$"
!roblema/ *e #uiere encontrar un programa #ue intercambie dos segmentos de un arreglo b
con dominio <m..p,, es decir, dados m? n ? p y el arreglo b de la 'igura siguiente/
0onde @ es el valor original del arreglo b. El arreglo b #uedar modi'icado como en la
'igura siguiente/

El programa slo podr declarar un n2mero constante de variables adicionales de tipos
bsicos y utili(ar slo operaciones de intercambio de dos elementos de un arreglo ms las
propias a de los tipos bsicos.

*olucin/
ACmo comen(aramosB. *i los dos segmentos del arreglo son del mismo largo tendramos
un problema ms simple #ue resolver +e)ercicio/ &acer un procedimiento llamado
IntercambiarIguales #ue intercambie dos segmentos dis)untos de igual largo de un arreglo,
se pasar como parmetros el arreglo, el ndice inicial de cada segmento y el largo de los
segmentos a intercambiar,. *upongamos #ue el procedimiento IntercambiarIguales consiste
en intercambiar dos segmentos dis)untos de igual largo. >eamos si podemos resolver
nuestro problema en t%rminos de este problema ms simple.
*uponga por el momento #ue el segmento b<m..n, es mas largo #ue b<n..p,. Consideremos
#ue el segmento b<m..n, consiste de dos segmentos, el primero de los cuales es del mismo
largo #ue b<n..p, +ver diagrama +a, dado ms aba)o,. Entonces los segmentos de igual largo
x1 y y pueden ser intercambiados obteni%ndose el diagrama +b,- adems, el problema
original puede ser resuelto intercambiando los segmentos x2 y x1. Estas dos secciones
pueden ser de distintos largos, pero el largo del mayor segmento es menor #ue el largo del
mayor segmento del problema original, por lo #ue hemos hecho alg2n progreso.
1hora supongamos #ue en lugar del primer segmento del problema original, es el segundo
segmento el #ue tiene largo mayor, es decir, b<n..p, es ms grande. Este caso es ilustrado en
$$
m n
p9
@<m..n,
b/
@<n..p,
m mCp9n
p9
@<n..p,
b/
@<m..n,
m
mCp9n p9
x
1
b/
y
+a,
+b,
n
x
2
m
mCp9n p9
y
b/
x
1
n
x
2
el diagrama +c,, y el procedimiento IntercambiarIguales puede ser utili(ado para
trans'ormar el arreglo como en el diagrama +d,.
1hora tratemos de llevar esta idea a un programa. .os diagramas +b, y +d, indican #ue
despu%s de e)ecutar IntercambiarIguales, n siempre es el ndice in'erior de la seccin ms a
la derecha a ser intercambiada. .o cual es cierto tambi%n al comien(o.
*upongamos #ue en +b, x1 es mas largo #ue x2, tendremos la situacin siguiente/
0onde x1 = x
1
1 x
2
1 , x2 y x
2
1 tienen el mismo largo. 0espu%s de intercambiar x2 y x
2
1
mediante IntercambiarIguales obtenemos/
Dote #ue los segmentos <m..h, y <E..p, ya estn en el sitio #ue les corresponde, y hay #ue
intercambiar los subsegmentos <h..n, y <n..E, del segmento <h..E,. !or lo tanto, podemos
obtener el invariante/
*in embargo, note #ue el algoritmo re#uiere la comparacin de los largos de b<n..E, y
b<h..n,. Fambi%n, el procedimiento IntercambiarIguales re#uiere los largos de los
segmentos. !or lo tanto puede resultar me)or tomar los largos de los segmentos en lugar de
sus ndices e7tremos. !or lo #ue el invariante ! se convierte en el predicado : ? i n9m
:? ) p9n, )unto con/
$G
m
mCp9n p9
x
1
b/
y
+c,
+d,
n
x
2
m
mCp9n p9
y
b/
x
1
n
x
2
m
h
p9
Ha intercam9
biado
b/
n
Intercambiar
con b<n..E,
E
Ha intercam9
biado
Intercambiar
con b<h..n,
m
n9i
p9
Ha intercam9
biado
b/
n
Intercambiar con
b<n..nC),
nC)
Ha intercam9
biado
Intercambiar con
b<n9i..n,
+bJ,
m
mCp9n p9
y
b/
x
2
n
x
2
1
x
1
1
+bJJ,
m
h p9
y
b/
x
2
1
n
x2 x
1
1
E
E)ercicio/ e7presar el invariante ! como un predicado.
3sando la 'uncin de cota decreciente t K ma7 +i,),, el programa es como sigue/
< const m, n, p/ entero-
var b/ arreglo <m..p, de entero-
var i, )/ entero-
8 !recondicin/ m ? n ? p ;
i,) /K n9m, p9n-
8 Invariante/ !, cota/ t ;
do i L ) IntercambiarIguales+b, n9i, n, ),- i /K i9)
<M i ? ) IntercambiarIguales+b, n9i, nC)9i, i,- ) /K )9i
od-
8 ! i K ) ;
IntercambiarIguales+b, n9i, n, i,
8 !ostcondicin ;
M
Como nota interesante, resulta #ue si eliminamos del programa anterior las llamadas al
procedimiento IntercambiarIguales, el programa #ue resulta es el algoritmo de Euclides
para determinar el mximo comn divisor, !D"n#m, p#n$, de n#m % p#n- es decir, el
m7imo com2n divisor de los largos de los segmentos originales/
< const m, n, p/ entero-
var i, )/ entero-
8 !recondicin/ m ? n ? p ;
i,) /K n9m, p9n-
8 Invariante/ : ? i : ? ) 6C0+n9m, p9n, K 6C0+i,), , cota/ ma7+i,), ;
do i L ) i /K i9)
i ? ) ) /K )9i
od-
8 i K ) K 6C0+n9m,p9n, ;
M
E)ercicios/ pgina ""N del Ories.
7.1.&. 'e(inamiento de Datos
>eamos a trav%s de un e)emplo sencillo en #u% consiste el re'inamiento de datos/
!roblema/ &acer un procedimiento #ue calcule todas las soluciones comple)as de la
ecuacin 17
"
C@7CCK:, con 1, @ y C reales. *uponga #ue cuenta con una 'uncin #ue
permite calcular la ra( cuadrada de un n2mero real no negativo. .a especi'icacin de esta
'uncin es como sigue/
real Pai(Cuadrada+entrada 7 / real,
$N
8 !re/ 7KQ Q : ;
8 !ost/ devuelve Q ;
Dote #ue en la ecuacin 1.7
"
C@.7CCK:, la operacin suma +C, se reali(a sobre n2meros
comple)os, es decir, es la suma sobre n2meros comple)os, al igual #ue el producto +.,. !or lo
tanto nuestro problema involucra ob)etos #ue pertenecen a los tipos de datos +o clases,/
n2meros reales y n2meros comple)os.
Duestro pseudolengua)e nos permite hacer programas #ue manipulen tipos de datos
cuales#uiera, en particular el tipo de dato n2mero comple)o. *in embargo, cuando
programamos en un lengua)e de programacin particular, el re'inamiento de datos es
necesario llevarlo a cabo si nuestro lengua)e de programacin no provee el tipo n2mero
comple)o. 1 continuacin llevamos a cabo el desarrollo del programa en pseudolengua)e y
utili(aremos re'inamiento de datos para representar los n2meros comple)os mediante un par
de n2meros reales correspondientes a la parte real y la parte imaginaria del n2mero
comple)o.
.a especi'icacin del programa sera/
< const 1, @, C/ real-
var con)/ Con)unto de D2mero comple)o-
8 !re/ verdad ;
*
8!ost/ con) K 87 / +7 D2mero comple)o, +1.7
"
C @.7 C C K :, ; ;
M
Dote #ue la especi'icacin anterior involucra los tipos de datos n2mero real,, n2mero
comple)o y con)unto de n2meros comple)os.
Como no se impone ninguna condicin adicional a los valores de los coe'icientes del
polinomio, slo #ue sean n2meros reales, debemos hacer un anlisis por casos, pues
dependiendo de los valores de los coe'icientes tenemos di'erentes maneras de proceder para
calcular las races del polinomio. !or lo tanto, dividimos el espacio de estados en 'uncin
de los coe'icientes del polinomio y dependiendo del valor #ue %stos puedan tener, habr una
solucin algortmica distinta al problema.
!or la teora asociada a la especi'icacin del problema, el polinomio ser de segundo grado
cuando 1 : y las races vienen dadas por la ecuacin/
1 . "
C . 1 . G @ @
"

&abr dos races comple)as si el discriminante, @
"
R G.1.C, no es cero- en cuyo caso las
races comple)as son/
"
@ @ G.1.C
".1
+
y
"
@ @ G.1.C
".1

. Fendr una sola ra(
$S
comple)a si el discriminante es cero. Cuando 1 K : y @ :, el polinomio es de primer
grado, y e7istir una sola ra(. H cuando 1 K :, @ K : y C K :, todo n2mero comple)o es
solucin. Cuando 1K:, @K: y C :, no e7istir solucin.
!or lo tanto podemos hacer una especi'icacin ms concreta donde introducimos una
variable entera n #ue nos indica el n2mero de soluciones #ue tiene la ecuacin 1.7
"
C @.7 C
CK:. Tue no haya solucin ser e#uivalente a nK:. &ay una sola ra( es e#uivalente a nK
y la variable 7 contendr la ra(. &ay dos soluciones es e#uivalente a nK" y las soluciones
#uedarn almacenadas en las variables 7 y 7". Fodo n2mero comple)o es solucin de la
ecuacin 1.7
"
C @.7 C CK:, si y slo si nK$. 3na especi'icacin ms concreta +o re'inada,
sera/
< const 1, @, C/ real-
var 7, 7"/ D2mero comple)o-
var n/ entero-
8 !re/ verdad ;
*
8!ost/ +nK: + 7/ 7 D2mero comple)o/ 1.7
"
C @.7 C C : , ,

+nK + 7/ 7 D2mero comple)o/ 1.7
"
C @.7 C C K : 7 K 7 , ,
+nK" + 7/ 7 D2mero comple)o/ 1.7
"
C @.7 C C K : 7 K 7 7 K 7" , ,

+nK$ + 7/ 7 D2mero comple)o/ 1.7


"
C @.7 C C K :, , ;
M
Dote #ue la variable con) desaparece en la nueva especi'icacin, pues la teora del
problema nos permiti concluir #ue el n2mero de soluciones es :, , " in'inito, y esto lo
representamos mediante la variable entera n, y dos variables comple)as 7 y 7". !or lo
tanto, al con)unto con) de la especi'icacin original lo hemos podido representar
mediante las variables n, 7 y 7". Con esta nueva representacin hemos hecho un
re'inamiento de datos. .a relacin e7istente entre con) y su representacin en t%rminos de
n, 7 y 7", se denomina Invariante de Acoplamiento, y este es/
+con)K: nK:, +con)K nK con)K87;,
+con)K" nK" con) K 87, 7";, +con)Kcon)unto de los n2meros comple)os nK$,
1 e'ectos de desarrollar el programa, la postcondicin T: T T" T$ puede ser
reescrita en t%rminos de 1, @ y C, con la 'inalidad de obtener una postcondicin #ue nos
permita desarrollar un programa.
.a nueva especi'icacin sera/
< const 1, @, C/ real-
var 7, 7"/ D2mero comple)o-
var n/ entero-
8 !re/ verdad ;
$7
*
8!ost/ + n K : +1K: @K: C:, ,
+ n K + + 1 K : @ : , + 1 : @
"
9 G.1.C K : , ,
+ 1.7
"
C @.7 C C K : , ,
+ n K " 1 : + 1.7
"
C @.7 C C K : , +@
"
R G1C :,
+ 1.7"
"
C @.7" C C K : , 7 7" ,
+ n K $ 1 K : @ K : C K : , ;
M
El programa completo sera/
< const 1, @, C/ real-
var 7, 7"/ D2mero comple)o-
var n/ entero-
var disc/ real-
8 !re/ verdad ;
i(
+1 K : @ K : C K :, n /K $
<M +1 K : @ K : C :, n /K :
<M +1 K : @ : , n /K -
7 /K 9C5@
<M +1 :, disc /K @U@9GU1UC-
i( disc K : n /K - 7 /K 9@5+"U1,
<M disc : n /K "-
7 /K
@ disc
"U1
+
-
7" /K
@ disc
"U1

(i
(i
8!ost/ + n K : +1K: @K: C:, ,
+ n K + + 1 K : @ : , + 1 : @
"
9 G.1.C K : , ,
+ 1.7
"
C @.7 C C K : , ,
+ n K " 1 : + 1.7
"
C @.7 C C K : , +@
"
R G1C :,
+ 1.7"
"
C @.7" C C K : , 7 7" ,
+ n K $ 1 K : @ K : C K : , ;
M
&emos introducido la variable disc con el propsito de aumentar la e'iciencia del
programa calculando una sola ve( el discriminante de la ecuacin de segundo grado.
$V
En este punto hemos encontrado un algoritmo #ue resuelve el problema. El algoritmo
manipula di'erentes tipos de datos, entre los #ue se encuentra el tipo n2mero comple)o. *i
nuestro lengua)e de programacin no posee el tipo n2mero comple)o debemos aplicar
Refinamiento de Datos para representar el tipo n2mero comple)o en t%rminos de los tipos
concretos de datos de nuestro lengua)e de programacin, es decir, los tipos #ue o'rece el
lengua)e. Dote #ue en la 'ase de especi'icacin del problema tambi%n podemos hacer
re'inamiento de datos, tal y como sucedi en nuestro e)emplo, en donde representamos al
con)unto solucin con) por las variables n, 7 y 7".
El proceso de re'inamiento de datos #ue se sigue para obtener un programa a partir del
algoritmo anterior es el siguiente/
, Pepresentar el tipo abstracto de dato D2mero comple)o en t%rminos de tipos ms
concretos de datos. Esto signi'ica representar los valores del tipo abstracto en t%rminos
de un con)unto de valores de tipos concretos. !or e)emplo, a un n2mero comple)o x
podemos hacer corresponder un par de n2meros reales xr y xi #ue representan
respectivamente la parte real y la parte imaginaria del n2mero comple)o x. El
Invariante de Acoplamiento sera/ 7 K 7r C 7iUi. Dote #ue hemos podido decidir
representar a un n2mero comple)o mediante su representacin polar +mdulo y ngulo,
en lugar de su representacin cartesiana.
", 3tili(ando el invariante de acoplamiento debemos implementar, mediante 'unciones y5o
procedimientos, las operaciones asociadas al tipo de dato en t%rminos de su
representacin por tipos concretos. .as operaciones a implementar debern ser las
operaciones del tipo #ue son utili(adas en nuestro algoritmo, aun#ue el con)unto de
operaciones a implementar podra ser mayor si #ueremos #ue la implementacin del
tipo de dato sea utili(ada por otros programas #ue utilicen esas operaciones sobre el
tipo. Implementar una operacin del tipo signi'ica de'inir una 'uncin o un
procedimiento por cada operacin. !or e)emplo, si se suman dos n2meros comple)os en
nuestro algoritmo, debemos hacer una 'uncin #ue reciba como parmetros de entrada
dos n2meros comple)os representados por tipos concretos y devuelva el n2mero
comple)o resultante de la suma, representado en t%rminos de los tipos concretos.
3n n2mero comple)o x lo representaremos por un arreglo de dos n2meros reales,
llam%moslo ax, tal #ue se cumple el invariante de acoplamiento/
Invariante de acoplamiento/ x K ax<:M C ax<M U i
.a 2nica operacin sobre n2meros comple)os #ue necesitamos en nuestro programa es
poder crear un n2mero comple)o conociendo su parte real y su parte imaginaria. !ara esto,
de'inimos la 'uncin ConstruirComplejo como sigue/
arreglo de real (un ConstruirComple)o+entrada 7r, 7i/ real,
8!re/ verdad;
8!ost/ 0evuelve un arreglo, denot%moslo 7, #ue representa al n2mero comple)o
7<:MC7<MUi;
$4
<
var 7/ arreglo <:..", de real-
7<:M /K 7r-
7<M /K 7-
Devolver +7,
M
El programa completo sera/
< const 1, @, C/ real-
var 7a, 7"a/ arreglo )*..&$ de real-
var n/ entero-
var disc, rai(disc/ real-
8 !re/ verdad ;
i(
+1 K : @ K : C K :, n /K $
<M +1 K : @ K : C :, n /K :
<M +1 K : @ : , n /K -
7a /K ConstruirComple)o+9C5@,:,
<M +1 :, disc /K @U@9GU1UC-
i( disc K : n /K -
7a /K ConstruirComple)o"9@5+"U1,,:,
<M disc L : n /K "-
rai(disc /K Pai(Cuadrada+disc,-
7a /K ConstruirComple)o"+9@ C rai(disc,5+"U1,,:,-
7"a /K ConstruirComple)o"+9@ 9 rai(disc,5+"U1,,:,
<M disc ? : n /K "-
rai(disc /K Pai(Cuadrada+9disc,-
7a /K ConstruirComple)o"9@5+"U1,,rai(disc5+"U1,,-
7"a /K ConstruirComple)o"9@5+"U1,,9rai(disc5+"U1,,
(i
(i
8!ost/ + n K : +1K: @K: C:, ,
+ n K + + 1 K : @ : , + 1 : @
"
9 G.1.C K : , ,
+7 K 7a<:MC7a<M.i, + 1.7
"
C @.7 C C K : , ,
+ n K " 1 : + 1.7
"
C @.7 C C K : , +@
"
R G1C :,
+7 K 7a<:M C 7a<M.i, +7" K 7"a<:M C 7"a<M.i,
+ 1.7"
"
C @.7" C C K : , 7 7" ,
+ n K $ 1 K : @ K : C K : , ;
M
G:
Dote, por e)emplo, #ue como el tro(o de programa original siguiente/
i( disc K : n /K - 7 /K 9@5+"U1,
<M disc : n /K "-
7 /K
@ disc
"U1
+
-
7" /K
@ disc
"U1

(i
satis'ace la especi'icacin/
8 !re/ 1 : disc K @U@9GU1UC ;
8 !ost/ n K " 1 : + 1.7
"
C @.7 C C K : , + 1.7"
"
C @.7" C C K : , 7 7";
entonces podemos demostrar, utili(ando el invariante de acoplamiento, #ue el tro(o de
programa siguiente/
i( disc K : n /K -
7a /K ConstruirComple)o"9@5+"U1,,:,
<M disc L : n /K "-
rai(disc /K Pai(Cuadrada+disc,-
7a /K ConstruirComple)o"+9@ C rai(disc,5+"U1,,:,-
7"a /K ConstruirComple)o"+9@ 9 rai(disc,5+"U1,,:,
<M disc ? : n /K "-
rai(disc /K Pai(Cuadrada+9disc,-
7a /K ConstruirComple)o"9@5+"U1,,rai(disc5+"U1,,-
7"a /K ConstruirComple)o"9@5+"U1,,9rai(disc5+"U1,,
(i
satis'ace la especi'icacin/
8 !re/ 1 : disc K @U@9GU1UC ;
8 !ost/ n K " 1 : + 1.7
"
C @.7 C C K : , + 1.7"
"
C @.7" C C K : , 7 7"
+7 K 7a<:M C 7a<M.i, +7" K 7"a<:M C 7"a<M.i,;
En el programa propuesto para hallar las soluciones comple)as de la ecuacin 1.7
"
C @.7 C
C K :, la representacin de un n2mero comple)o en t%rminos de tipos concretos no #ueda
oculta al programador de la aplicacin. *in embargo, los constructores de procedimientos y
'unciones permiten implementar separadamente las operaciones del tipo- y un programador
#ue las utilice le basta slo con conocer la especi'icacin de los procedimientos y 'unciones
correspondientes. .o ideal hubiese sido #ue el programador pudiese utili(ar el tipo
Nmero complejo sin tener #ue conocer como se representa en t%rminos de tipos concretos
+en nuestro caso un n2mero comple)o se representa por arreglo<:..", de real,. 3na de las
G
venta)as de no tener #ue conocer la representacin del tipo estriba en el hecho de poder
modi'icar la representacin del tipo Nmero complejo sin #ue esto a'ecte a los programas
#ue usan el tipo Nmero complejo. Esto lo trataremos de subsanar en la seccin 7..$.
donde introduciremos un constructor de tipos de datos.
7.1.+. Encapsulamiento % ,cultamiento de Datos
Cuando utili-amos un tipo de dato, como n2mero comple)o, no nos debera interesar
cmo se representa el tipo en 'uncin de los tipos concretos. .o #ue realmente nos debe
interesar es poder operar con ob)etos de ese tipo. El programa se vuelve ms complicado de
entender cuando modi'icamos el algoritmo inicial para escribirlo en 'uncin de los tipos
concretos de datos como hicimos en el e)emplo anterior.
*i el lengua)e de programacin permite de'inir aparte los tipos abstractos de datos
+encapsulamiento de datos, y #ue su implementacin est% oculta al programador
+ocultamiento de datos,, entonces tendremos un mecanismo para reali(ar programas ms
claros. En =1>1, por e)emplo, e7iste el constructor C.1** +clase, #ue permite
implementar encapsulamiento y ocultamiento de datos.
Introducimos a continuacin un constructor de nuestro pseudolengua)e #ue nos permitir
implementar un tipo abstracto de datos. Este ser un 'ragmento de programa #ue se de'ine
aparte del programa #ue lo usa.
Con este constructor lograremos/
0e'inir y encapsular un tipo abstracto de datos.
Wcultar la representacin de un tipo abstracto de datos en t%rminos de tipos
concretos.
Tue los programas #ue hagamos sean ms claros, al no tener #ue implementar los
tipos abstractos de datos en el mismo 'ragmento de programa #ue los usa.
.a posibilidad de de'inir variables cuyo tipo sea el #ue de'inimos.
Introducir la nocin de clases y objetos. Dociones propias de la programacin
orientada a objetos +paradigma utili(ado por el lengua)e de programacin =1>1,.
!rocedamos a de'inir nuestro nuevo constructor, utili(ando como e)emplo el tipo abstracto
de dato nmero complejo. 3n n2mero comple)o, es un tipo cuyos valores se pueden
representar por dos n2meros reales, la parte real y la parte imaginaria. !or otro lado, e7isten
operaciones asociadas a n2meros comple)os como son sumar dos n2meros comple)os,
multiplicarlos, determinar su parte real, determinar su parte imaginaria. Es decir, al tipo est
asociado un con)unto de valores y un con)unto de operaciones aplicables a ob)etos de ese
tipo. En programacin orientada a ob)etos, una clase es el tipo de dato de un ob)eto, la cual
incluye un con)unto de atributos #ue corresponden al valor de un ob)eto de la clase. !or
otro lado, una clase posee mtodos. .os m%todos son procedimientos o 'unciones #ue estn
asociados a ob)etos de la clase. !or e)emplo, determinar la parte real de un n2mero
comple)o puede corresponder a un m%todo de la clase de los n2meros comple)os.
G"
El constructor de tipos de nuestro pseudolengua)e permitir declarar variables de la 'orma/
var c1, c, c!/ NumeroComplejo-
donde NumeroComplejo es el nombre de la clase #ue implementa a los n2meros comple)os.
!rocederemos a hacer la especi'icacin de la clase NumeroComplejo con las operaciones/
construir un n2mero comple)o a partir de su parte real y su parte imaginaria, construir un
n2mero comple)o a partir de su representacin polar, obtener la parte real de un n2mero
comple)o, obtener la parte imaginaria de un n2mero comple)o, sumar un n2mero comple)o
a otro n2mero comple)o. .uego haremos una implementacin de esta clase donde
representamos a un n2mero comple)o por el par 'ormado por su parte real y su parte
imaginaria. .os nuevos t%rminos #ue aparecen en la especi'icacin sern e7plicados a lo
largo de la seccin.
.a especificacin de la clase NumeroComplejo es la siguiente/
clase NumeroComplejo
var x" n2mero comple)o-
constructor NumeroComplejoCartesiano+entrada pr, pi/ real,
8!re/ verdad;
8!ost/ 7 K pr C piUi ;
constructor NumeroComplejo#olar+entrada modulo, angulo/ real,
8!re/ modulo : : angulo ? $S: ;
8!ost/ 7 K +moduloU coseno+angulo,, C +modulo U seno+angulo,, U i ;
real metodo #arte$eal+ ,
8!re/ verdad ;
8!ost/ devuelve la parte real de x ;
real metodo #arteImaginaria+ ,
8!re/ verdad ;
8!ost/ devuelve la parte imaginaria de x ;
metodo %umar+entrada otro" NumeroComplejo,
8!re/ x&' ;
8!ost/ x & ' ( otro)x ;
(inclase
.a especi'icacin anterior indica #ue la clase +o tipo abstracto de dato, NumeroComplejo
estar 'ormada por ob)etos cuyos valores son n2meros comple)os y cuyas operaciones son/
NumeroComplejoCartesiano, NumeroComplejo#olar, #arte$eal, #arteImaginaria, %umar.
G$
.as operaciones NumeroComplejoCartesiano y NumeroComplejo#olar son operaciones
constructoras de la clase, es decir, permiten crear ob)etos tipo n2mero comple)o, de all la
palabra reservada constructor en la especi'icacin. .as otras operaciones se de'inen con
la palabra reservada metodo para indicar #ue son operaciones #ue se aplican a ob)etos de
la clase.
!or lo tanto, con la declaracin/
var c/ NumeroComplejo-
estamos indicando #ue c es un ob)eto de tipo NumeroComplejo. H podemos asignar un
valor a c con la siguiente instruccin/
c /K NumeroComplejoCartesiano+",:,
0espu%s de #ue se e)ecute esta instruccin, c tendr el valor " C :Ui. Este ser el valor del
atributo x de c. *i denotamos el atributo x de c por c)x, tendremos c)x K "C:Ui despu%s de
e)ecutarse la instruccin anterior.
Implementacin y re'inamiento de la clase NumeroComplejo en el pseudolengua)e/
1hora procederemos a reali(ar un re'inamiento de datos en la de'inicin de la clase
NumeroComplejo, mediante la representacin de un n2mero comple)o por el par 'ormado
por su parte real y su parte imaginaria.
.os atributos de la nueva clase incluyen los atributos asociados a la representacin de los
valores del tipo en t%rminos de tipos concretos y cuya relacin se establece mediante el
invariante de acoplamiento. En nuestro caso los atributos de un ob)eto de la clase
NumeroComplejo sern su parte real y su parte imaginaria. 0enotemos estos atributos por
preal y pimag respectivamente. !arte de la clase se escribe/
clase NumeroComplejo
var preal, pimag" real- ............
!or lo tanto el invariante de acoplamiento entre la especi'icacin inicial y la
implementacin #ue estamos desarrollando sera/
x & preal ( pimag * i
donde x es el atributo de la especi'icacin y, preal y pimag son los atributos de la
implementacin.
1s la clase re'inada e implementada es la siguiente/
clase NumeroComplejo
var preal, pimag" real-
GG
8 .nvariante de acoplamiento/ x & preal ( pimag * i ;
constructor NumeroComplejoCartesiano+entrada pr, pi/ real,
8!re/ verdad;
8!ost/ preal & pr pimag & pi ;
<
preal "& pr+ pimag "& pi
M
constructor NumeroComplejo#olar+entrada modulo, angulo/ real,
8!re/ modulo : : angulo ? $S: ;
8!ost/ preal & ,modulo* cos,angulo-- pimag & ,modulo * sen,angulo-- ;
<
preal & ,modulo* coseno,angulo--+ pimag & ,modulo * seno,angulo--
M
real metodo #arte$eal+ ,
8!re/ verdad ;
8!ost/ devuelve preal ;
< 0evolver +preal, M
real metodo #arteImaginaria+ ,
8!re/ verdad ;
8!ost/ devuelve pimag ;
< 0evolver +pimag, M
metodo %umar+entrada otro" NumeroComplejo,
8!re/ preal& ' pimag & . ;
8!ost/ preal & ' ( otro)preal pimag & . C otro)pimag ;
<
preal "& preal ( otro)preal+
pimag "& pimag ( otro)pimag
M
(inclase
.as normas de estilo de programacin orientada a ob)etos obligan a #ue un atributo de
representacin de un ob)eto no sea visible a los programas #ue usan dicho ob)eto. Esto es
para re'or(ar la t%cnica de ocultamiento de datos/ no importa cmo se implementa un tipo
abstracto de datos, lo #ue importa es su comportamiento para poder usarlo, y por lo tanto,
no se debe tener acceso a la representacin interna de sus atributos. !or lo #ue no podemos
hacer re'erencia a la parte real de un ob)eto c1 tipo NumeroComplejo, en un programa #ue
usa dicho ob)eto. .a e7presin c1)preal no puede aparecer en otro tro(o de programa #ue
no sea la implementacin de la clase NumeroComplejo.
GN
Dote, sin embargo, #ue dentro de la implementacin de la clase NumeroComplejo, en el
m%todo %umar, hemos accedido directamente a los atributos del ob)eto otro- esto se debe a
#ue otro es tipo NumeroComplejo y dentro de la implementacin de una clase se permite
tener acceso a los atributos de otros ob)etos de la misma clase.
El ocultamiento de los atributos de representacin permite tambi%n #ue sea posible
modi'icar ms adelante la implementacin de NumeroComplejo +por e)emplo,
representndolo en coordenadas polares, sin #ue esto a'ecte a los programas #ue usen el
tipo NumeroComplejo.
*i #ueremos obtener la parte real del n2mero comple)o c1, la instruccin de llamada a
m%todo +anloga a llamada a procedimiento o 'uncin, sera c1.#arte$eal+ ,, la cual
corresponde en este caso a una llamada a una 'uncin asociada a ob)etos de la clase
NumeroComplejo, y #ue devuelve la parte real del ob)eto c1. *i #ueremos la parte
imaginaria del ob)eto c1, escribiramos c1)#arteImaginaria, -.
Dote #ue las llamadas a m%todos arriba indicadas han sido aplicadas al ob)eto c1. En
programacin DW orientada a ob)etos, este ob)eto c1 sera el primer argumento o parmetro
de tales procedimientos o 'unciones. En programacin orientada a ob)etos, se dice #ue c1 es
el ob)eto receptor de la llamada. !or lo tanto, al apegarnos a la 'iloso'a de orientacin a
ob)etos, el m%todo #arte$eal tendr un parmetro 'ormal implcito adicional #ue
corresponder al n2mero comple)o al #ue se le aplica la llamada. *iguiendo la convencin
utili(ada por muchos lengua)es orientados a ob)etos +entre ellos =1>1,, a tal parmetro
implcito lo llamaremos t/is. En este momento podemos observar la di'erencia e7istente
entre un procedimiento o 'uncin convencional y un m%todo de una clase/ una llamada a
m%todo +por e)emplo, c1)#arte$eal, -, debe ir asociada a un ob)eto- decimos #ue la llamada
a m%todo es un mensaje #ue estamos pasando al ob)eto receptor. !or lo tanto, en la sinta7is
de la instruccin de llamada a m%todo debe aparecer e7plcitamente el ob)eto receptor del
mensa)e +en el e)emplo anterior es c1,.
El ob)eto receptor t/is de una llamada a m%todo siempre es un parmetro 'ormal de
entrada#salida. !or lo tanto, los m%todos tienen un argumento implcito adicional #ue de
haberse indicado e7plcitamente, tendra la siguiente declaracin/
entrada#salida t/is" NumeroComplejo
!or lo tanto, la instruccin/
x "& c1)#arte$eal+ ,
e#uivaldra, si hacemos e7plcito el parmetro asociado al ob)eto, a/
x "& #arte$eal+ c1,
*in embargo, esta 2ltima notacin no es correcta para los m%todos de'inidos en una clase.
GS
!odemos hacer mencin e7plcita de t/is en la implementacin de la clase
NumeroComplejo. !or e)emplo el m%todo #arte$eal, - lo hemos podido escribir/
real metodo #arte$eal+ ,
8!re/ verdad ;
8!ost/ devuelve t/is.preal ;
< 0evolver +t/is)preal, M
En general, el proceso de re'inamiento, ocultamiento y encapsulamiento de datos consiste
en especi'icar el tipo abstracto de dato y luego implementarlo en el lengua)e de
programacin utili(ando las herramientas de encapsulamiento del lengua)e. .os programas
#ue utilicen el tipo implementado lo harn mediante la declaracin de variables #ue
representarn ob)etos del tipo implementado y mediante paso de mensa)es a ob)etos del
tipo.
>eamos el programa completo re'inado para el clculo de las soluciones comple)as de la
ecuacin 17
"
C@7CC K :, utili(ando la clase NumeroComplejo +colocamos en itlicas los
elementos asociados a la clase NumeroComplejo,/
< const 1, @, C/ real-
var x1, x" NumeroComplejo-
var n/ entero-
var disc, rai(disc/ real-
8 !re/ verdad ;
i(
+1 K : @ K : C K :, n /K $
<M +1 K : @ K : C :, n /K :
<M +1 K : @ : , n /K -
x1 "& NumeroComplejoCartesiano,0C1.,2-
<M +1 :, disc /K @U@9GU1UC-
i( disc K : n /K -
x1 "& NumeroComplejoCartesiano,0.1,*'-,2-
<M disc : n /K "-
i( disc > : rai(disc /K Pai(Cuadrada+disc,-
x1 "& NumeroComplejoCartesiano,
,0.(rai3disc-1,*'-,2-+
x "& NumeroComplejoCartesiano,
,0.0rai3disc-1,*'-,2-
<M disc ? : rai(disc /K Pai(Cuadrada+9disc,-
x1 "&
NumeroComplejoCartesiano,0.1,*'-,
rai3disc1,*'--+
x "&
NumeroComplejoCartesiano,0.1,*'-,
0 rai3disc1,*'--+
G7
(i
(i
(i
8!ost/ + n K : +1K: @K: C:, ,
+ n K + + 1 K : @ : , + 1 : @
"
9 G.1.C K : , ,
+ 1.7
"
C @.7 C C K : , ,
+ n K " 1 : + 1.7
"
C @.7 C C K : ,
+ 1.7"
"
C @.7" C C K : , 7 7" ,
+ n K $ 1 K : @ K : C K : , ;
M
Wtro e)emplo de Pe'inamiento de 0atos/ Pegistro estudiantil
3n registro estudiantil consiste de un con)unto de datos sobre estudiantes. !or cada
estudiante, el registro estudiantil contiene el n2mero de carnet del estudiante y su ndice
acad%mico. *e #uiere implementar la siguiente aplicacin/ dado un registro estudiantil y
una lista de D estudiantes, determinar si entre los estudiantes de la lista se encuentra un
estudiante con mayor ndice del registro estudiantil. *e deber crear la clase
$egistro4studiantil #ue permita de'inir ob)etos de este tipo. 1 e'ectos de la aplicacin, el
registro estudiantil estar creado y contiene al menos un estudiante, lista de estudiantes
estar almacenada en un arreglo de enteros de largo D #ue contiene los carnets de los
estudiantes.
.a clase $egistro4studiantil podra tener las siguientes operaciones/ agregar un estudiante
al registro estudiantil, dar el ndice de un estudiante, determinar un estudiante con me)or
ndice, veri'icar si el registro tiene estudiantes, veri'icar si el registro tiene un estudiante
dado- aparte de los constructores. !or otro lado, suponemos #ue el n2mero de estudiantes
#ue estn en el registro est acotado por un cierto n2mero 61Q.
.a especi'icacin de esta clase sera/
clase $egistro4studiantil
var carnets/ con)unto de enteros-
var indices/ 'uncin de enteros a reales-
const 5'6/ entero-
8.nvariante de !lase/ ,c" c carnets" c 7 2- ,i" i rango,indices-" 1 i 8-
,dom,indices-& carnets- carnets 5'6 ;
constructor $egistro4studiantil+ ,
8!re/ verdad;
8!ost/ carnets & indices & ;
GV
metodo 'gregar4studiante+entrada nuevoc/ entero- entrada nuevoi/ real,
8!re/ nuevoc 7 2 1 nuevoi 8 carnets & C indices & I carnets9 5'6
nuevoc carnets ;
8!ost/ carnets & C :nuevoc; indices & I :,nuevoc, nuevoi-;;
real metodo <arIndice+entrada c/ entero,
no modi(ica/ carnets, indices
8!re/ c carnets ;
8!ost/ devuelve indices ,c- ;
metodo =n5ejor4studiante+salida c/ entero- salida i/ real,
no modi(ica/ carnets, indices
8!re/ carnets ;
8!ost/ c carnets i & indices ,c- , otroc" otroc carnets" indices,otroc- i - ;
booleano metodo >ay4studiantes+ ,
no modi(ica/ carnets, indices
8!re/ verdad ;
8!ost/ <evuelve el valor de la expresin ,carnets , ;
booleano metodo 4sta4studiante+entrada c/ entero ,
no modi(ica/ carnets, indices, 5'6
8!re/ verdad ;
8!ost/ 0evuelve ,c carnets- ;
(inclase
Dote #ue la clase $egistro4studiantil tiene ms de un atributo, a di'erencia de la clase
NumeroComplejo. El invariante de clase premite establecer las relaciones #ue deben
e7istir entre los atributos de la clase. Introducimos la 'rase reservada no modi(ica para
indicar #ue el m%todo no modi'icar los atributos #ue aparecen en la lista, y as abreviar el
uso de variables de especi'icacin. 3na implementacin de la clase $egistro4studiantil es/
clase $egistro4studiantil
var seccarnets/ arreglo )*..5'6$ de entero-
var secindices/ arreglo )*..5'6$ de real-
var cantidad/ entero-
const 5'6/ entero-
8.nvariante de !lase/ : cantidad 61Q
+i/ : i ? cantidad/ seccarnets<iM L : secindices<iM N,
+i/ : i ? cantidad : ) ? cantidad/
i ) seccarnets<iM seccarnets<)M, ;
G4
8.nvariante de Acoplamiento/ carnets K 8 seccarnets<iM / : i ? cantidad ;
indices K 8 +seccarnets<iM,secindices<IM, / : i ?
cantidad ; ;
constructor $egistro4studiantil+ ,
8!re/ verdad ;
8!ost/ cantidad & 2 ;
<
cantidad "& 2
M
metodo 'gregar4studiante+entrada nuevoc/ entero- entrada nuevoi/ real,
no modi(ica/ 5'6
8!re/ nuevoc 7 2 1 nuevoi 8 seccarnets & %C sec indices & %I cantidad& C
cantidad 9 5'6 ,i" 2i9cantidad" secarnets?i@ nuevoc- ;
8!ost/ seccarnets & %C,C"nuevoc- sec indices & %I,C"nuevoi- cantidad K C C ;
<
seccarnets?cantidad@ "& nuevoc+
secindices?cantidad@"&nuevoi+
cantidad "& cantidad ( 1+
M
real metodo <arIndice+entrada c/ entero,
no modi(ica/ seccarnets, secindices, 5'6, cantidad
8!re/ ,j" 2 j 9cantidad" seccarnets?j@ & c- ;
8!ost/ 0evuelve 3, tal Aue" ,j" 2 j 9cantidad" seccarnets?j@ & c secindices?j@&3 - ;
< var j" entero-
j /K :-
do ,seccarnets?j@ c- j"& j(1
0evolver +secindices?j@,
M
metodo =n5ejor4studiante+salida c/ entero- salida i/ real,
no modi(ica/ seccarnets, secindices, 5'6,cantidad
8!re/ cantidad :;
8!ost/ ,j" 2 j 9cantidad" seccarnets?j@ & c secindices?j@& i
, B" 2 B 9 cantidad" secindices?B@ i -- ;
<
var B, j / entero-
B /K - j /K :-
do B cantidad i' secindices?B@ 7 secindices?j@ j"& B
<M secindices?B@ secindices?j@ sEip
'i-
B "& B(1
N:
od-
c /K seccarnets<)M-
i/K secindices<)M
M
booleano metodo >ay4studiantes+ ,
no modi(ica/ seccarnets, secindices, 5'6, cantidad
8!re/ verdad ;
8!ost/ 0evuelve el valor de la e7presin ,cantidad :, ;
<
0evolver+cantidad :,
M
booleano metodo 4sta4studiante+entrada c/ entero ,
no modi(ica/ seccarnets, secindices, 5'6, cantidad
8!re/ verdad ;
8!ost/ 0evuelve ,j" 2 j 9cantidad" seccarnets?j@ & c-;
<
var ) / entero-
) /K :- b/K verdad-
do , ) cantidad- b i' ,seccarnets?j@ c- )/K )C
<M ,seccarnets?j@ & c- b"&falso
'i
do-
0evolver +) ? cantidad,
M
(inclase
.a aplicacin, utili(ando la clase $egistro4studiantil sera/
<
const $eg/ PegistroEstudiantil-
const estudiantes/ arreglo <:..D, de entero-
const N/ entero-
var carnetCmejor, j / entero- var indiceCmejor, indiceCest/ real-
var esta/ booleano-
8 !re/ D : + )/ : ) ? D / $eg)4sta4studiante+estudiantes<jM,, ;
esta /K 'also-
Peg.3n6e)orEstudiante,carnetCmejor, indiceCmejor-+
j /K :-
do +j N, + esta, indiceCest /K Peg.0arIndice+estudiantes?j@ , -
i' + indCest & indiceCmejor, esta /K verdad
N
<M + indCest indiceCmejor, sEip
'i-
j"&j(1
do
8!ost/ esta ,j" 2 j 9N" , 3" 3 D " $eg)4sta4studiante,3-
,$eg)<arIndice,3- $eg)<arIndice,estudiantes?j@-- -- ;
M
E)ercicios/
, 1plicar encapsulamiento de datos los tipos Pelacin @inaria y 6#uina de tra(ados.
", 0ado un con)unto 'inito 1 de n2meros enteros se #uiere hacer un programa #ue
construya dos con)untos, uno #ue contenga los n2meros negativos de 1 y otros con
los n2meros no negativos de 1. +ayuda/ representar el tipo con)unto mediante
arreglos,.
$, E)ercicios pag. 7 Castro.
7.&. Es/uemas de recorrido % bs/ueda secuencial
&asta ahora hemos considerado dos 'ormas bsicas de acceder a los datos, como son el
acceso secuencial y el acceso directo. En el captulo S hemos visto algunos algoritmos #ue
acceden ya sea secuencial o directamente los elementos de un arreglo.
.a di'erencia entre acceso secuencial y directo se puede ilustrar con un e)emplo
matemtico. Pecordemos #ue los n2meros de Xibonacci se de'inen como la sucesin/ :, ,
, ", $, N, V,... donde el elemento n9%simo, Xib+n,, es la suma de Xib+n9, y Xib+n9", +para n
mayor #ue ,. *i deseamos obtener el n9%simo n2mero de Xibonacci debemos partir de los
elementos Xib+:, y Xib+, e ir obteniendo cada ve( el siguiente de la secuencia como suma
de los dos anteriores, hasta llegar a construir el n9%simo. Este m%todo de obtener el n9%simo
n2mero de Xibonacci, obteniendo los valores de la secuencia uno tras otro se denomina
acceso secuencial/ para acceder a un t%rmino se debe haber accedido antes a los t%rminos
anteriores. 1hora bien, si conoci%ramos una 'rmula cerrada, 'uncin de n solamente, para
determinar el n9%simo n2mero de Xibonacci, entonces no tenemos #ue hacer un acceso
secuencial de la sucesin para obtenerlo, bastara slo con aplicar la 'rmula para obtener el
n2mero. En este 2ltimo caso, tenemos un acceso directo al n9%simo n2mero de Xibonacci,
es decir, conocemos su valor a partir solamente de su posicin, n, en la sucesin.
Wtros e)emplos de acceso secuencial y directo son/ b2s#ueda de una escena en una cinta de
video +acceso secuencial,, reproduccin de una cancin espec'ica en un disco compacto
+acceso directo,. 3tili(aremos el tipo archivo secuencial y el tipo arreglo para ilustrar los
es#uemas bsicos de algoritmos para acceso secuencial.
N"
7.&.1. 0os Tipos Abstractos Arc1ivo 2ecuencial de Entrada % Arc1ivo
2ecuencial de salida
3n arc1ivo secuencial de entrada es 'undamentalmente una secuencia de ob)etos de un
mismo tipo base, donde el acceso a cada ob)eto slo puede llevarse a cabo de manera
secuencial, es decir, para acceder al n9%simo ob)eto, hay #ue recorrer los n9 ob)etos
anteriores a %l en la secuencia. !or otro lado, el largo de la secuencia no es conocido a
priori. 3n e)emplo de archivo secuencial de entrada es la entrada estndar de un
computador como el teclado- tambi%n, un archivo almacenado en una cinta magn%tica,
archivo estndar de te7to.
El valor de un ob)eto del tipo 1rchivo *ecuencial de Entrada est compuesto por/
, 3na secuencia * de elementos de tipo base tipo base.
", 3n ndice i, #ue llamaremos el elemento ndice del archivo secuencial, #ue
representar el elemento del archivo al #ue se puede tener acceso en una instruccin
de acceso al siguiente elemento de la secuencia.
3n archivo secuencial de entrada slo tiene operaciones #ue permiten tener acceso
secuencialmente a cada uno de los elementos de la secuencia comen(ando desde el primero
hasta el 2ltimo. Como no conoceremos de antemano el largo del archivo +es decir, de la
secuencia asociada al archivo,, tendremos un operador +Xin1rchivo+,, #ue nos indica si se
ha alcan(ado el 'in del archivo +es decir, de la secuencia,.
1.* denotar la secuencia, 1.i denotar el elemento ndice del archivo secuencial 1 de
entrada.
.as operaciones sobre archivos secuenciales son/
9 1brirEntrada+1,s,/ Es un constructor y permite crear un archivo con secuencia s. El
valor de la secuencia 1.* del archivo ser la secuencia s de tipo tipo base y el
elemento ndice 1.i tendr valor :.
9 Xin1rchivo+1,/ es una 'uncin booleana. 0evuelve verdad si y slo si se ha
alcan(ado el 'in del archivo, es decir, si el ndice 1.i de 1 es igual al largo de la
secuencia 1.*.
9 .eer+1,7,/ coloca en 7 el elemento de 1.* cuyo ndice es 1.i e incrementa en a
1.i. Esta operacin es aplicable si y slo si 1.i ? 1.*
Dote #ue el elemento ndice 1.i de un archivo secuencial 1, divide implcitamente a la
secuencia 1.* en dos partes/ el segmento 1.*<:..i, #ue llamaremos parte i(#uierda de 1 y
denotaremos por pi+1, y el segmento 1.*<i..D,, donde D es el largo de *, #ue llamaremos
parte derecha de 1 y denotaremos por pd+1,. Dote #ue basta con conocer e7actamente uno
de los tres valores/ pi+1,, 1.i pd+1,, para #ue los otros dos #ueden precisamente
N$
determinados. Dote adems #ue si en un programa utili(amos un archivo de entrada 1, en
cual#uier momento de la e)ecucin del programa pi+1, representa los elementos #ue han
sido ledos por el programa, es decir, los elementos #ue han sido obtenidos mediante una
operacin .eer+...,, y este hecho lo podemos utili(ar en las aserciones de las aplicaciones
#ue usen archivos secuenciales de entrada.
.a especi'icacin de la clase 1rchivo de Entrada es/
clase 1rchivoEntrada
var */ secuencia de tipo base-
var i/ entero-
8 Invariante de clase/ : i *;
constructor 1brirEntrada+entrada s/secuencia de ob)etos de tipo base,
8 !re/ verdad;
8 * K s i K : ;
booleano metodo Xin1rchivo+ ,
no modi'ica/ i, *
8 !re/ verdad;
8 0evuelve +i K *, ;
metodo .eer+salida 7/ tipo base,
no modi'ica/ *
8!re/ i ? * i K I ;
8!ost/ 7 K *<IM i K IC ;
(inclase
3n arc1ivo secuencial de salida slo tiene operaciones #ue permiten construir su
secuencia asociada, es decir, permiten escribir elementos al 'inal de la secuencia. Do se
permite leer elementos en archivos de salida. E)emplo de archivo de salida es la salida
estndar del computador, por e)emplo, una ventana de inter'a( de comandos.
.as operaciones sobre archivos de salida son/
9 1brir*alida+1,s,/ Es un constructor y permite crear un archivo con secuencia s. El
valor de la secuencia 1.* del archivo ser la secuencia s de tipo tipo base.
9 Escribir+1,7,/ agrega como 2ltimo elemento de la secuencia 1.*, un nuevo
elemento cuyo valor ser el del ob)eto 7.
.a especi'icacin de la clase 1rchivo*alida es/
NG
clase 1rchivo*alida
var */ secuencia de tipo base-
constructor 1brir*alida+entrada s/secuencia de ob)etos de tipo base,
8 !re/ verdad;
8 * K s ;
metodo Escribir+entrada 7/ tipo base,
8!re/ *K Q ;
8!ost/ * K Q ?7L ;
(inclase
7.&.&. Acceso 2ecuencial4 Es/uemas de recorrido % bs/ueda secuencial
>eamos dos problemas sencillos #ue permiten es#uemati(ar los modelos 'undamentales de
algoritmos #ue act2an sobre secuencias/
, *umar todos los valores de una secuencia de enteros.
", >eri'icar si aparece la letra YZJ en una 'rase.
En el primer problema debemos recorrer todos los elementos de la secuencia y a cada
elemento hacerle un mismo tratamiento. Wtros problemas #ue tienen estas mismas
caractersticas son/ clculo del m7imo n2mero de una secuencia de enteros, contar el
n2mero de caracteres iguales a Y'J en una secuencia de caracteres. 0iremos #ue estos
problemas los podemos resolver con un es/uema de recorrido secuencial, #ue ya hemos
visto en el caso de arreglos y #ue daremos mas adelante para el tipo archivo secuencial.
En el segundo problema la estrategia correcta de solucin debera ser #ue al momento en
#ue se encuentra el elemento buscado no debe continuarse el recorrido de la secuencia, de
'orma #ue slo se llega al 'inal de la secuencia si el elemento buscado no aparece en %sta.
0iremos #ue este problema lo podemos resolver con un es/uema de bs/ueda secuencial,
#ue daremos mas adelante.
1hora bien, pueden e7istir situaciones en donde no conocemos el largo de las secuencias
#ue #ueremos tratar. !or lo tanto necesitamos alguna 'orma de identi'icar cundo hemos
tratado el 2ltimo elemento de la secuencia. *i la secuencia viene representada por un
archivo secuencial de entrada, el operador Xin1rchivo+ , nos indica cuando hemos
alcan(ado el 'inal de la secuencia.
Es/uemas de recorrido secuencial4
*upongamos #ue tenemos la secuencia * de largo D, y #ueremos sumar los elementos de *,
el problema lo podemos resolver como sigue/
NN
< const D/ entero- 8 D : ;
const @/ secuencia de entero-
var suma/ entero-
8 * K D ;
suma /K :-
E /K :-
8Invariante/ +suma K + i / : i ? E/ *<iM, ,+:ED,-
Cota decreciente/ D9E ;
do E D
suma /K suma C *<EM-
E /K EC
od
8 suma K + i / : i ? D/ *<iM, ;
M
!odemos abstraer los elementos bsicos de un algoritmo de recorrido/ dar un mismo
tratamiento a cada elemento de la secuencia, recorriendo la secuencia del primero al 2ltimo.
!or lo tanto, si la especi'icacin de un problema es como sigue/
8 * es una secuencia de elementos de largo D;
recorrido
8 *e trataron de la misma 'orma todos los elementos de *;
Entonces la solucin obedecer al siguiente es#uema de programa, conocido como
es/uema de recorrido secuencial/
0eclaracin de variables
Iniciali(ar tratamiento +entre otras cosas, dar acceso al primer elemento de la secuencia, por
e)emplo, iniciali(ar i en :,
8 Inv/ +han sido tratados los elementos de *<:..i,
Cota/ *9 i;
do +no se ha alcan(ado el 'inal de *, por e)emplo, i largo de *,
Fratar elemento *<iM-
1cceder al siguiente elemento +es decir incrementar i en ,
od
Fratamiento 'inal
1plicacin de es#uemas de recorrido secuencial cuando representamos el tipo secuencia
mediante el tipo archivo secuencial de entrada/
*upongamos #ue en un archivo secuencial de entrada tenemos una secuencia de n2meros
enteros y #ueremos calcular la suma de los elementos del archivo secuencial. .a solucin
sera utili(ar el es#uema de recorrido secuencial/
NS
< const */ secuencia de entero-
var 1/ 1rchivoEntrada-
var suma, 7/ entero-
8 verdad ;
1.1brirEntrada+*,-
suma /K :-
8Invariante/ +suma K + ) / : ) ? pi+1,/ pi+1,<)M,, * K pi+1, pd+1,-
Cota decreciente/ *9pi+1, ;
do Xin1rchivo+1, 1..eer+7,-
suma /K suma C 7-
od
8 suma K + i / : i ? */ *<iM, ;
M
En el invariante del algoritmo anterior pi+1, es igual a 1.i- sin embargo, no utili(amos
1.i por el principio de ocultamiento de datos, es decir, no conocemos la representacin
interna de un archivo secuencial de entrada.
Es/uemas de bs/ueda secuencial4
Pesolvamos el problema de determinar si un te7to * contiene la letra YZJ, lo cual nos
ayudar a abstraer el es#uema correspondiente. .a especi'icacin sera/
< const */ secuencia de caracter-
var esta/ booleano-
8 verdad ;
buscar
8 esta +i/ : i ? */ *<iM K YZJ , ;
M
3na solucin sera/
< const D/ entero-
const */ secuencia de caracter-
var esta/ booleano-
8 D : +*K D, ;
esta /K 'also-
E /K :-
8 Invariante/ + esta +i/ : i ? E/ *<iM K YZJ , , +:ED,- Cota/ D9E ;
do E D esta /K esta +*<EM K YZJ ,-
E /K EC
od
8 esta +i/ : i ? */ *<iM K YZJ , ;
M
N7
!ara no tener #ue recorrer toda la secuencia, habiendo ya encontrado el elemento buscado,
el es#uema asociado sera el siguiente/
< const D/ entero-
const */ secuencia de caracter-
var esta/ booleano-
8 D : +*K D, ;
esta /K 'also-
E /K :-
8 Invariante/ + esta +i/ : i ? E/ *<iM K YZJ , , +:ED,- Cota/ D9E ;
do E D esta
esta /K +*<EM K YZJ ,-
E /K EC
od
8 esta +i/ : i ? */ *<iM K YZJ , ;
M
*i la secuencia no es vaca, tenemos la solucin/
< const D/ entero-
const */ secuencia de caracter-
var esta/ booleano-
8 D L : +*K D, ;
E /K :-
8 Invariante/ +i/ : i ? E/ *<iM K YZJ , +:ED9, - Cota/ D9E ;
do E D9 *<EM YZJ
E /K EC
od
esta /K +*<EM K YZJ,
8 esta K +i/ : i ? */ *<iM K YZJ , ;
M
Dote #ue en la guardia del programa anterior no podemos colocar E D pues cuando E es D
el valor *<DM no est de'inido y dara error. El programa anterior no 'unciona para
secuencias de largo :, mientras #ue el #ue lo precede s.
!or lo tanto, si la especi'icacin de un problema es como sigue/
8 * es una secuencia de elementos;
bsAueda
8 esta K e7iste un elemento 7 de * #ue cumple la propiedad !+7, ;
Entonces la solucin obedecer al siguiente es#uema de programa, conocido como
es/uema de bs/ueda secuencial/
NV
0eclaracin de variables-
Iniciali(ar tratamiento +entre otras cosas, iniciali(ar i en : y esta en 'also,-
8 Inv/ +*,*"/ +* K * *", +esta K e7iste un elemento en * #ue cumple !+7,, +i K
*, ,-
Cota/ *9 i ;
do i * esta
esta /K !+*<iM,-
1cceder al siguiente elemento +es decir incrementar i en ,
od-
Fratamiento 'inal
1plicacin de es#uemas de b2s#ueda secuencial cuando representamos el tipo secuencia
mediante el tipo archivo secuencial de entrada/
!roblema/ dado un archivo secuencial de entrada se #uiere veri'icar si el archivo contiene la
letra YZJ
< const */ secuencia de caracter-
var 1/ 1rchivoEntrada-
var esta/ booleano-
var 7/ carcter-
8 verdad ;
1.1brirEntrada+*,-
esta /K 'also-
8Invariante/ + esta +i/ : i ? pi+1,/ pi+1,<iM K YZJ , , * K pi+1, pd+1,-
Cota decreciente/ pi+1, ;
do Xin1rchivo+1, esta 1..eer+7,-
esta /K +7 K YZJ ,-
od
8 esta +i/ : i ? */ *<iM K YZJ , ;
M
E)ercicios/
, 0ado un archivo secuencial de caracteres hacer un programa #ue veri'i#ue si el
archivo contiene el carcter YZJ. Considere dos casos/ #ue e7ista o no centinela.
", &acer un programa #ue cree un archivo secuencial #ue contenga los cuadrados de
los primeros n n2meros naturales.
$, 0ado un archivo secuencial de caracteres, 'ormular y discutir varios programas #ue
permitan encontrar el n2mero de ocurrencias de la subsecuencia hola +!iense en
una versin donde la idea abstracta es contar las ocurrencias del ob)eto hola en
una secuencia de ob)etos, los ob)etos pueden ser palabras de largo G, y as aplicar el
es#uema de recorrido secuencial visto en esta seccin,.
G, &acer un programa #ue lea dos archivos secuenciales donde los elementos estn
ordenados en 'orma ascendente y cree un archivo secuencial con todos los
elementos de los dos archivos originales ordenados en 'orma ascendente
N4
Wtros e)emplos de diseo descendente/ Fratamiento de pare)as de caracteres +pag. 4"9::
Castro, para mostrar diseo descendente utili(ando es#uemas de recorrido y re'inamiento
de datos.
S:
S

También podría gustarte