Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Wuolah Free Tema 7 Informatica
Wuolah Free Tema 7 Informatica
Programación estructurada
Es difı́cil hacer un resumen de las ideas de la programación estructurada a lectores que no tienen
cierta experiencia en programación. Esto sucede porque la programación estructurada pretende
evitar cierto tipo de situaciones que aparecen en programas grandes y medianos, pero que no
se advierten en los ejemplos dados a principiantes. Una de estas situaciones es la siguiente: un
programador escribe un diagrama de flujo tal y como aparece en la parte derecha de la figura 7.1.
Transcurrido cierto tiempo, el mismo programador es requerido para realizar una modificación
en el mismo. Éste intenta modificar el diagrama, pero la tarea le resulta ardua. Analizando los
motivos por los que el trabajo no avanza con rapidez se puede observar que:
• Es difı́cil hallar el punto en el cual hay que eliminar un bloque o insertar uno nuevo, pues
todo está enmarañado.
• Incluso aunque el diagrama tuviera una mejor disposición gráfica, cuesta trabajo ver si
121
122 TEMA 7. PROGRAMACIÓN ESTRUCTURADA
una modificación de una parte dará resultados indeseables en otra, debido al gran número
de interconexiones que hay.
Y los problemas no acaban ahı́. Tras realizar los cambios, el programador deberá probar el
nuevo programa para comprobar su correcto funcionamiento. Cada vez que se detecte un error
deberá volver a repetir el tedioso proceso de modificación. Los problemas descritos no serı́an
tales si el programador hubiera podido escribir el diagrama de flujo de forma parecida a la de
la figura 7.1 (izquierda), en la que se aprecia que no existen cruces de lı́neas y que cada módulo
tiene una entrada y una salida. Sobre estos dos aspectos se insistirá más adelante, por ahora no
es necesario comentar más las ventajas que para cualquier proyecto supone el tener programas
legibles y comprensibles.
Los diagramas se dice que tienen flujo lineal cuando no existen conexiones de vuelta atrás o
laterales. El flujo lineal se puede conseguir restringiendo las uniones entre bloques constructivos
a estructuras de entrada única y salida única. Es decir, usando para la confección del diagrama
de flujo grupos de bloques a los cuales llega sólo una flecha y de los cuales parte sólo una flecha.
La secuencia, la selección entre alternativas y la iteración forman un conjunto suficiente de
módulos constructivos para describir cualquier algoritmo. Es decir, es posible siempre realizar
c MRA & JAAR
� 2010 DISA. ESI. US. 123
un diagrama de flujo que contiene sólo las estructuras citadas. En la figura 7.2 se tienen tales
estructuras; se puede ver que son de entrada única y salida única.
sí no no
pregunta cuerpo del bucle pregunta
módulo 1
sí
opción 1 opción 2 condición cuerpo del bucle
módulo 2
sí
no
Estas estructuras permitidas reciben los nombres que se indican a continuación. De izquierda
a derecha en la citada figura 7.2 se tiene un par de bloques formando una secuencia, una bi-
furcación y bloques articulados en una estructura disyuntiva, una bifurcación con conexión
hacia atrás formando un blucle o estructura repetitiva con salida en cola y, finalmente, una
bifurcación formando una estructura repetitiva con salida en cabeza.
En lo sucesivo se usarán estas estructuras (y ninguna otra) para realizar los diagramas
de flujo, pero antes de pasar a los ejemplos es preciso comentar cómo se va a producir la
descomposición del problema global en módulos.
Inicio
Lectura de datos
Cálculo de
resultados
Escritura de
resultados
Fin
Inicio de
Inicio de lectura Inicio de cálculo
escritura de
de datos de resultados
resultados
Es importante que antes de pasar al siguiente nivel se compruebe la validez del diagrama
actual. Para ello se ha de comprobar que las construcciones utilizadas pertenecen al conjunto
de las estructuras permitidas.
Los cálculos en secuencia no presentan dificultad alguna desde el punto de vista algorı́tmico.
Los diagramas de flujo resultantes son lineales, sin bifurcaciones ni ciclos o repeticiones, y por
tanto de fácil creación.
Inicio
Leer a
Leer b
c a+b
7.2.1 Ejercicios
Se propone realizar el diagrama de flujo de algoritmos que resuelvan las tareas siguientes:
Nota importante: en este libro la palabra positivo se ha de entender como ”mayor que cero”
quiere esto decir que el número cero no forma parte del conjunto de los números positivos.
Inicio
Leer x
sí no
¿ x < 0 ?
r -x r x
Las bifurcaciones se pueden encadenar para dar solución a situaciones más complejas. Por
ejemplo considérese la función: NC(x, y), con (x, y) ∈ IR2 �→ c ∈ {1, 2, 3, 4}. Esta función calcula
el número de cuadrante en que se encuentra el punto (x, y) de IR2 . Se desea desarrollar un
algoritmo que lea las coordenadas x e y de un punto del plano (suponiendo que x �= 0 y que
y �= 0) y calcule y escriba r =NC(x, y).
El diagrama de la figura 7.6 presenta una posible solución mediante el uso de bifurcaciones
en cascada.
Figura 7.6: Programa que escribe el cuadrante en el cual se sitúa el punto en el plano (x, y).
7.3.1 Ejercicios
Utilizando las ideas que se han presentado en los puntos anteriores desarrolle algoritmos que
den solución a los problemas siguientes:
x f (x)
x ∈ [−1, 3) 10 − x
x > 50 1
resto 0
5. Leer las componentes de un vector de IR2 (x e y). Calcule el valor de r que se define como
r =NC(x, y) si x �= 0, y �= 0 y r = 0 si x = 0 o si y = 0.
no
cuerpo condición
sí
condición cuerpo
sí
no
Figura 7.7: Estructuras repetitivas con control de salida en la cola (diagrama de la izquierda) y
control de salida en la cabeza (diagrama de la derecha).
El diagrama de la figura 7.8 presenta una posible solución al problema haciendo uso de
una estructura repetitiva con salida en la cola. Es muy conveniente dedicar unos minutos a
comprobar que el algoritmo resuelve el problema. Para ello pruebe a seguir mediante cálculos
a mano los pasos indicados en el diagrama para n = 1, n = 2, n = 3. Una vez realizado este
ejercicio no le resultará difı́cil determinar que el algoritmo ha de funcionar necesariamente para
todo n > 0.
Inicio
Leer n
k 1
vk k·k -4
Variable
Dato, dimensión de v n
entera
k k+1
Variable
Resultado, vector v v vector de
no enteros
¿ k > n ? Índice para recorrer v. Variable
k
Variable auxiliar entera
sí Componente k-ésima de v
Variable
calculada mediante la vk
entera
Fin expresión k 2 -4
Figura 7.8: Construcción de un vector mediante proceso iterativo con salida en la cola.
En el diagrama de la figura 7.9 se muestra otro diagrama que utiliza un bucle con salida en
la cabeza. Compruebe también mediante pruebas a mano que este diagrama realiza la misma
tarea que el del ejemplo anterior.
Debido a la sencillez de este ejemplo puede parecer que ambas maneras de realizar una
estructura cı́clica son equivalentes de un modo trivial. Aunque es cierto que se puede pasar
de una a otra esto no siempre se logra con facilidad. Además hay que tener en cuenta que
algunos lenguajes de programación están orientados a usar una de ellas, por ejemplo en el caso
de MATLAB siempre se prefiere la comprobación de salida en cabeza.
El bloque constructivo llamado módulo puede usarse para mejorar el aspecto visual de los
diagramas de flujo. En particular si un diagrama consta de varias estructuras repetitivas puede
ser interesante dedicar un módulo a cada uno de ellos. Para ilustrar esta idea considere el
problema cuyo enunciado es ”Se ha de leer una lista de n números reales, siendo n un entero
que ha de leerse previamente. Posteriormente se escribirá la lista en orden inverso. Se supondrá
que n > 0”. La figura 7.10 muestra el diagrama de flujo de una posible solución. Dicho diagrama
incluye dos módulos que se detallan en diagramas separados. La tabla de objetos es única pues
130 TEMA 7. PROGRAMACIÓN ESTRUCTURADA
Inicio
Leer n
k 1
sí
¿ k > n ?
no Variable
Dato, dimensión de v n
entera
vk k·k -4
Variable
Resultado, vector v v vector de
enteros
k k+1
Índice para recorrer v. Variable
k
Variable auxiliar entera
Componente k-ésima de v
Variable
calculada mediante la vk
entera
Fin expresión k 2 -4
Figura 7.9: Construcción de un vector mediante proceso iterativo con salida en cabeza.
los diagramas correspondientes a los módulos se interpretan como parte del diagrama general.
A todos los efectos se trata por tanto de un único diagrama con la particularidad de que algunas
partes (los módulos) se detallan de forma separada.
Puede verse que los módulos ayudan a comprender mejor el algoritmo. Cada parte del
diagrama puede abarcarse de un golpe de vista, facilitando su comprensión y el análisis de su
validez.
7.4.1 Ejercicios
Los siguientes ejercicios se pueden resolver con ayuda de estructuras cı́clicas. Utilice módulos en
aquellos casos en que el diagrama resultante sea demasiado largo. Recuerde que los diagramas
no pueden cortarse.
1. Leer las componentes de un vector de números reales de dimensión 10. Escribirlo luego en
la pantalla.
3. Leer n (suponiendo que es entero y > 0). Leer a continuación las n componentes de un
c MRA & JAAR
� 2010 DISA. ESI. US. 131
k 1 k n
Leer n
no no
¿ k ≤ n ? ¿ k ≥ 1 ?
Lectura de sí sí
vector v
Leer v k Escribir vk
k k+1 k k-1
Escritura
inversa de
vector v
Figura 7.10: Diagrama de flujo con módulos para el problema de la escritura inversa.
132 TEMA 7. PROGRAMACIÓN ESTRUCTURADA
vector de números reales dimensión n. Calcular y escribir luego la media aritmética de sus
componentes.
8. Leer n (suponiendo que es entero y mayor que uno). Construir un vector v ∈ IRn×1 tal
que vk = vk−1 /3 + 0.5 para k = 2, ..., n y siendo v1 = 1.
9. Leer n (suponiendo que es entero y mayor que dos). Construir un vector v ∈ IRn×1 tal que
sus componentes sean los términos de la sucesión de Fibonacci1 .
10. Se han medido las longitudes de tornillos procedentes de un mismo lote de fabricación.
Se han dispuesto en un vector v de dimensión n > 2. Se dispone de v y n. Diseñe un
algoritmo para�calcular la media y la varianza de las longitudes. La varianza se calcula
como var = n1 nk=1 (vk − µ)2 , siendo µ la media aritmética de las componentes de v.
El cuerpo de una estructura repetitiva no es necesariamente un módulo simple sino que puede
contener otras estructuras. En el punto anterior se han expuesto diversos ejemplos en los cuales
el cuerpo contiene exclusivamente estructuras en secuencia. No existe ningún impedimento para
que el cuerpo contenga estructuras selectivas o incluso otros ciclos.
Cuando un ciclo contiene a otro se obtiene una estructura doblemente repetitiva2 . En cada
iteración del ciclo externo se realizan varias repeticiones del cuerpo del ciclo interno.
Las repeticiones dobles son especialmente apropiadas para trabajar con matrices A ∈ IRm×n .
En muchas situaciones es preciso recorrer los elementos de la matriz para realizar de este modo
la lectura, escritura o cualquier otro cálculo. Se plantea en estos casos el problema de considerar
todos los posibles elementos akj de la matriz. Conviene recordar que el elemento genérico akj
tiene dos subı́ndices: k (filas) y j (columnas) que varı́an en los intervalos: k = 1, 2, ..., m y
j = 1, 2, ..., n.
1
La sucesión de Fibonacci comienza con a1 = 1, a2 = 1 y posteriormente cada término ak es la suma de los
dos anteriores ak−1 + ak−2 para k > 2.
2
Llamada frecuentemente bucles anidados por ser estas palabras la traducción literal de nested loops.
c MRA & JAAR
� 2010 DISA. ESI. US. 133
Para trabajar con matrices se puede emplear un ciclo dentro de otro. Normalmente el ciclo
externo recorre el ı́ndice de filas y el interno el ı́ndice de columnas. En la figura 7.11 se presenta
un diagrama de flujo que puede utilizarse para recorrer la matriz.
iniciar k a 1
sí
¿ k > m ?
no
iniciar j a 1
sí
¿ j > n ?
no
Operar con el
elemento a kj
Incrementar j
Incrementar k
Figura 7.11: Diagrama de flujo que permite recorrer una matriz gracias a dos estructuras repet-
itivas.
7.5.1 Ejercicios
Los ejercicios que se proponen a continuación se pueden resolver con la estructura de esta figura
7.11 (aunque alguno de ellos puede resolverse con estructuras más simples).
2. Construir una matriz A ∈ IRm×n cuyo elemento genérico akj viene dado por akj = k 2 − j.
3. Dada una matriz (se supone ya leı́da) A de dimensiones m × n, se quiere anular (poner a
cero) los elementos de su diagonal principal y escribir la matriz resultante.
4. Traza de una matriz. Dada una matriz cuadrada A ∈ IRn×n dada siendo n > 0 un entero
también dado se ha de diseñar un algoritmo que permita obtener la traza de A (suma de
los elementos de la diagonal).
5. Suma de matrices. Dadas (suponga que ya han sido leı́das) dos matrices A ∈ IRm×n y
B ∈ IRm×n se quiere calcular y escribir la matriz C obtenida como suma de las anteriores
C = A + B.
7. Submatriz triangular. Dada una matriz A ∈ IRm×n se desea calcular otra matriz B ∈ IRm×n
cuyos elementos son todos cero excepto los de la submatriz triangular inferior que son
iguales a los elementos de igual posición de A. Es decir, los elementos que están por de-
bajo de la diagonal principal de A se copian en B, el resto de elementos de B valen cero.
Se supone que tanto m como n son números enteros mayores que uno ya leı́dos.
8. Máximo de una matriz. Dada una matriz A ∈ IRm×n calcular el elemento mayor.
9. Máximo de cada fila. Dada una matriz A ∈ IRm×n con m > 1 y n > 1 dados se desea
calcular un vector v ∈ IRm cuya componente genérica vk es el mayor valor de la fila
k−ésima de A.
En este punto se presenta una serie de problemas que pueden ser resueltos con algoritmos que
combinan algunas de las estructuras explicadas en este tema.
�
3. Se desea calcular la suma s = nk=1 1/ak siendo los valores ak los elementos de la sucesión
dada por ak = ak−1 + ak−2 para k > 2, con a1 = 1 y a2 = 1. El lı́mite n ha de leerse del
teclado y se supone mayor que dos.
�
4. Se desea calcular la suma s = nk=1 1/k m siendo m y n dos números enteros positivos que
se suponen dados.
7.6.2 Ordenaciones
1. Dado un vector v de dimensión n cuyas componentes son todas positivas o cero se desea
reordenar sus componentes de mayor a menor. Por ejemplo, si
v = [2 3 8 5 4]
w = [8 5 4 3 2]
2. Repetir el ejercicio anterior pero sin usar un vector auxiliar como w. El resultado que se
pretende conseguir es que el propio vector v tenga sus componentes ordenadas.
3. Igual que el anterior pero suponiendo que v contiene cantidades positivas y negativas, por
ejemplo:
v = [−7 3 8 − 9 5 4 0 − 1]
ha de dar como resultado el propio vector reordenado ası́:
v = [8 5 4 3 0 − 1 − 7 − 9]
En este caso la ordenación produce un nuevo vector T o = [11.5 11.8 12 14 28], de donde
se obtiene la mediana que es el valor central 12.
Puede comprobar con los ejemplos anteriores que la mediana no coincide con la media
aritmética.
Para poder diseñar los algoritmos que resuelven algunos de los problemas propuestos a contin-
uación puede necesitar una función que elimine los decimales de números reales y obtener de
este modo números enteros. Esta función recibe el nombre de parte entera y puede denotarse
matemáticamente como ParteEntera(). De este modo x ← ParteEntera(3.14) es equivalente a
x ← 3.
1. Dado un número entero x mayor que uno se ha de escribir un uno si el número es par y
un cero en caso contrario.
2. Dados dos números enteros positivos p y q, p > q, se ha de escribir un uno si son divisibles
y cero si no lo son.
3. Dado un número entero x mayor que uno se ha de escribir la lista de sus divisores com-
prendidos en el intervalo (1, x).
4. Dado un número entero x mayor que uno se ha de escribir un uno si es primo y un cero en
caso contrario. Para ello ha de comprobar si x es divisible por algún entero en el intervalo
(1, x).
5. Dada una cantidad N > 1 calcular la raı́z cuadrada entera aproximada r. Se ha de cumplir
que r · r ≤ N < (r + 1) · (r + 1).
Por ejemplo, si N = 24 se tiene que r = 4 pues 4 · 4 = 16 ≤ 24 < 25 = 5 · 5.
6. Se ha de escribir un uno en el caso de que exista un trı́o (x, y, z)de números enteros positivos
tales que x2 + y 2 = z 2 . Limite la búsqueda a x ∈ (0, 100], y ∈ (0, 100]. En caso de que no
se encuentre solución se ha de escribir un cero.
7. Repita el ejercicio anterior pero escribiendo todas las soluciones que encuentre en el inter-
valo x ∈ (0, 1000], y ∈ (0, 1000].
8. Dados dos números enteros positivos p y q escriba un algoritmo que permita hallar el
máximo común divisor de los mismos.
9. Como aplicación del ejercicio anterior diseñe un algoritmo que permita descubrir si dos
enteros positivos son primos entre sı́, es decir si su máximo común divisor es uno.
c MRA & JAAR
� 2010 DISA. ESI. US. 137
7.6.4 Matrices
7.6.5 Leyes
La evolución de ciertas magnitudes del mundo real puede en ocasiones acomodarse a simples
leyes expresables de un modo similar a las sucesiones. En este apartado se proporcionan algunos
ejemplos que ilustran la forma en que el cálculo por ordenador ayuda a la Ciencia y la Ingenierı́a.
1. La cantidad de un cierto isótopo radioactivo presente en una mezcla varı́a con el tiempo
pues el isótopo se descompone emitiendo radiación. Se denota mediante y(k) la cantidad
en gramos de isótopo en el instante de tiempo t = k medido en años. Unos cientı́ficos han
descubierto que se cumple que y(k) = 0.99 · y(k − 1). Si un barril de desechos radioactivos
contiene 1000 gramos de isótopo, ¿cuál será la cantidad de isótopo presente al cabo de 500
años?
2. La velocidad de un paracaidista en su descenso al suelo una vez que ha abierto el paracaı́das
se denota mediante v(k) (m/s), siendo k el tiempo que lleva cayendo medido en segundos,
k > 1. Se ha especulado con la idea de que dicha velocidad sigue la ley: v(k) = v(k −
1) + 10 − 0.4(v(k − 1))2 . Sabiendo que una caı́da tı́pica puede durar 5 minutos y que
el paracaı́das se suele abrir con una velocidad de 100 Km/h, ¿con qué velocidad llega al
suelo?
3. Se sabe que la cantidad de bacterias de cierta especie en un cultivo es x(k) = 1.1x(k −
1) siendo k el tiempo medido en horas, k > 1. Si al cabo de la primera hora x(1) se
contabilizaron 100 unidades, ¿cuántas habrá al cabo de un dı́a?
La comprobación del buen funcionamiento de un algoritmo es una tarea difı́cil y para la cual
no existen reglas generales. En muchos casos sin embargo el sentido común y el razonamiento
138 TEMA 7. PROGRAMACIÓN ESTRUCTURADA
La prueba del algoritmo con datos controlados consiste en preparar una serie de valores de los
datos para los cuales se conoce el resultado correcto. Posteriormente se siguen los pasos del
algoritmo y se comprueba si los resultados que el algoritmo produce coinciden con los resultados
conocidos de antemano.
Como ejemplo considere el problema de escribir un uno en caso de que cierto entero x sea
primo y cero en otro caso. Si se desea comprobar si cierto algoritmo A es correcto puede ser
buena idea probar A con x = 2 y comprobar que el resultado es que se escribe un uno. Si el
resultado no es este no hace falta comprobar más, pues un solo fallo sirve para invalidar A. Si
el resultado es correcto se puede pasar a probar A con x = 3 y repetir el proceso.
Es fácil ver que este método tiene el grave inconveniente de que hacen falta tantas pruebas
como posibles valores distintos puede tomar el dato x. En muchas ocasiones se recurre al método
de probar el algoritmo sólo en algunos valores elegidos. Por ejemplo con varios números primos
y otros no primos tanto grandes como pequeños. Hay que resaltar que este tipo de pruebas
no permite validar el algoritmo completamente. Esto es ası́ porque un algoritmo puede dar
resultados correctos en muchas situaciones y sin embargo no ser correcto universalmente pues
puede que contenga errores que no se han manifestado con esos datos.
No existe un procedimiento general para seleccionar valores de prueba para algoritmos, sin
embargo es posible dar algunos consejos como:
• probar valores particulares que puedan dar problemas como el cero (en el caso de que haya
divisiones), o los números negativos (si hay raı́ces cuadradas).
• probar los valores extremos de los datos, por ejemplo si se sabe que el dato x ∈ IR cumple
que x ∈ [5, 3] entonces merece la pena probar con los valores x = 3 y x = 5.
En muchos casos es posible aplicar el método matemático de prueba inductiva. Por ejemplo
cuando el dato de un algoritmo puede tomar cualquier valor n ∈ IN.
c MRA & JAAR
� 2010 DISA. ESI. US. 139
Este tipo de razonamiento permite decidir la corrección de algoritmos que contienen estruc-
turas iterativas. En estos casos los puntos que causan mayores problemas son las entradas y
salidas de los ciclos de repetición. Por este motivo hay que prestar mucha atención a los valores
iniciales asignados a ı́ndices y contadores antes de entrar en el ciclo, a la actualización de los
mismos dentro del cuerpo que se repite y finalmente a la condición de salida del ciclo.
7.7.3 Modularidad
El análisis de algoritmos se realiza entonces de una forma cómoda pues basta con probar
cada módulo de forma independiente. Cuando se han comprobado los módulos de un cierto
nivel puede pasarse al nivel superior. Las comprobaciones de un nivel superior pueden llevarse
a cabo sin necesidad de volver a utilizar o analizar los módulos de niveles inferiores. En lugar
de ello es posible sustituir mentalmente dichos módulos por mecanismos que automáticamente
proporcionan los resultados correctos. De este modo el análisis se lleva a cabo de forma jerárquica
lo cual permite avanzar con mayor rapidez y confianza.
Es posible ahora poner un par de ejemplos para aclarar las ideas sobre la programación estruc-
turada. Considere en primer lugar el diagrama que aparece en la parte izquierda de la figura
7.12. A la vista cómo están unidos los bloques ¿sabrı́a decir si es un diagrama bien estructurado?.
Para responder a esta cuestión resulta conveniente agrupar los bloques que forman secuencias
en módulos, de forma que la estructura subyacente quede expuesta con mayor claridad. Esto
140 TEMA 7. PROGRAMACIÓN ESTRUCTURADA
Este sencillo análisis permite determinar que la estructura del diagrama está de acuerdo con
las normas establecidas en este capı́tulo. Observe que para discutir sobre la estructura de un
diagrama no es preciso conocer las operaciones que se realizan en cada bloque. En efecto, la
estructura depende exclusivamente de las uniones entre bloques y no de su contenido.
Considere ahora el diagrama que se muestra en la parte izquierda de la figura 7.13. A primera
vista no parece haber nada que indique que el diagrama no sea estructurado (al menos no lo
parece para el principiante en esta materia). En la parte central y derecha de la figura se pone de
manifiesto que esto es un error. En efecto, el recuadro a trazos intenta encerrar una estructura
del tipo repetición o bucle con salida en cola. Sin embargo el recuadro no tiene solamente una
entrada y una salida como se requiere. De hecho, el recuadro es cortado por dos flechas de
entrada y por una de salida. Si uno intenta encerrar la estructura inferior mediante un recuadro
(véase parte derecha de la figura) ocurre nuevamente que no se cumple la regla de una única
entrada y una única salida. En este caso hay dos salidas y una sola entrada.
c MRA & JAAR
� 2010 DISA. ESI. US. 141