Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

Algoritmos Profesor Luna

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 82

Algoritmos y Estructuras de Datos

1



















A l g o r i t m os


y E s t r u c t u r a s


d e D a t o s









Z. Luna
Algoritmos y Estructuras de Datos
2

Algoritmos y Estructuras de Datos
3

Representacin de algoritmos:

Existen varias formas de representar algoritmos. Diagramas de flujo (no recomendado),
pseudocdigo, diagramas de Chapin, etc.
Adoptaremos en el curso los diagramas de Chapin.



Lenguajes de Programacin:

Una vez desarrollado un algoritmo en Chapin, debemos traducirlo a un lenguaje que sea
comprendido por la computadora. Hemos adoptado el lenguaje Pascal.



Constantes y variables:

A lo largo del desarrollo de un programa, habr entidades que no sufren cambios (son las
constantes) y otras que pueden ir cambiando su valor (son las variables).


Constantes:

Trabajaremos con constantes numricas, de caracter y booleanas.

Dentro de las numricas distinguiremos las que tienen punto decimal (3.1415 -745.2 22.0 0.0
0.0256 etc.) que llamaremos reales y las que no tienen punto decimal (17 -356 12988 0 22
-30000) que son las enteras.

Las constantes tipo carcter son por ejemplo c, Z, 9, -,

Las booleanas son dos true y false


Variables:

Son componentes del programa que pueden ir cambiando su valor o contenido a lo largo del
desarrollo del algoritmo. Las variables son identificadas por medio de nombres o identificadores.
(Pascal permite tambin identificar constantes por medio de identificadores).



Asignacin:

En el desarrollo de nuestros algoritmos nos encontraremos con formas del tipo
variable expresin

esto es lo que llamamos asignacin y significa asignar a la variable el resultado de la expresin

Cmo construimos una expresin? Por medio de la combinacin de constantes, variables,
operadores y funciones. Tambin emplearemos parntesis, cuyo uso ya conocemos

Algoritmos y Estructuras de Datos
4


Operadores:

Tenemos operadores aritmticos , relacionales , lgicos , de caracteres , etc.

Operadores aritmticos:

Son los conocidos + (suma) , - (resta) , * (multiplicacin) y / (divisin)
Para evaluar una expresin aritmtica hay reglas en cuanto a la fuerza de los operadores
+ y - tienen igual fuerza , pero menos fuerza que * y / (la conocida regla de que + y -
separan y * y / juntan). Pero ac debemos agregar que si hay una sucesin de operadores de
igual fuerza, se van evaluando las operaciones de izquierda a derecha. Por ejemplo si tenemos

3 * xx / y + 12 * z * qual * m / 17 / ra / p / s * ty * w + 11 * a / b / c * nu

estaramos representando la siguiente expresin con notacin algebraica comn

3 . xx 12 . z . qual . m . ty . w 11 . a . nu
---------- + -------------------------------- + ----------------
y 17 . ra . p . s b . c

las funciones tienen mas fuerza que los operadores y las expresiones entre parntesis deben ser
evaluadas prioritariamente, respetando dentro de ellas las prioridades enunciadas.

Operadores de relacin:

Se usan para comparar expresiones del mismo tipo, la mayora de las veces expresiones
aritmticas, pero pueden comparar expresiones de tipo caracter, booleanas (raro) ( por definicin
false es menor que true), o incluso, en Pascal, datos definidos por el programador.
El resultado de estas comparaciones es false o true.
Los operadores son
< (menor)
<= (menor o igual)
= (igual)
> (mayor)
>= (mayor o igual)
<> (distinto)

supongamos que tenemos las variables a = -3 b = 15 c = 8 jj = pepe w = luisito

la expresin 3 * a + b < 16 devolver el valor true
la expresin a + 2 * b > 4 * c devolver el valor false
la expresin a + b <> 12 devolver el valor false
la expresin c + b <= 36 devolver el valor true
la expresin w >= jj devolver el valor false

Operadores lgicos:

Son and , or y not ( y , o , no)
and y or vinculan dos expresiones lgicas y podramos decir que el resultado del and slo es
verdadero si las dos expresiones que vincula son verdaderas; el or slo resulta falso si las dos

Algoritmos y Estructuras de Datos
5

expresiones son falsas. El not slo se aplica a una expresin lgica, dando como resultado el
opuesto a la expresin. Todo esto podemos representarlos as

p q p and q p or q not q
F F F F V
F V F V F
V F F V
V V V V


El or que hemos definido es el inclusivo. Existe otro or, el exclusivo pero no lo usaremos en
el curso.
Se pueden armar expresiones lgicas complejas combinando operadores de relacin y
operadores lgicos. Para evaluar las mismas tambin existen reglas y prioridades, pero las
explicaremos en cada caso particular si es que se hace necesario usar alguna.





Volvamos a la sentencia de asignacin: variable expresin
La expresin debe ser del mismo tipo que la variable, es decir que si la variable es numrica, la
expresin debe ser numrica; si la variable es booleana, la expresin debe ser booleana; etc.
Por ejemplo, si x e y son dos variables numricas, la expresin booleana x=y tiene sentido y
devolver true si x e y son iguales y devolver false si son distintas.
Si z es una variable booleana, tiene sentido la asignacin z x=y


Si bien todava no estamos en condiciones de comprender el siguiente programa, mas adelante
pueden probarlo

program asignboo(input , output);
var z: boolean; x, y: real; rta: char;
begin write('Ingrese dos reales'); readln(x, y);
z := x=y;
if z then writeln('La variable z quedo en TRUE')
else writeln('La variable z quedo en FALSE');
write('Ingrese nuevamente dos reales'); readln(x, y);
z := x=y;
if z then writeln('La variable z quedo en TRUE')
else writeln('La variable z quedo en FALSE');
write('Pulse cualquier tecla para terminar . . .'); read(rta)
end.

Ingresen la primera vez que pide dos valores, por ejemplo, los valores 3.75 y 3.75 y vern que
la respuesta es La variable z quedo en TRUE.
Luego, cuando vuelve a pedir otros dos valores, ingresen por ejemplo 9.01 y 2.22 ahora la
respuesta ser La variable z quedo en FALSE.




Algoritmos y Estructuras de Datos
6


Tipos de datos:

A lo largo del curso trabajaremos con diferentes tipos de datos los que podemos clasificarlos de la
siguiente manera

integer (son los enteros, no tienen punto decimal)
real (son los reales, tienen punto decimal)
Standard bolean (son dos, true y false, o verdadero y falso)
char (son los caracteres: a K * 9 etc)
escalares . . . . . .


declarados (por el programador)


string (tiras de caracteres)
array (vectores, matrices, .)
estructurados record (registros)
file (archivos)
. . . . . .



Ntese que hemos puesto puntos suspensivos ya que la mayora de los compiladores (ste
incluido) admite mas tipos de datos. Por ejemplo, simplemente como comentario, hacemos notar
otros tipos de enteros que generalmente son admitidos:

shortint : enteros entre -128 y 127
longint : enteros entre -2147483648 y 2147483647 (puede llegar a ser muy til este tipo)
byte : enteros positivos entre 0 y 255
word : enteros positivos entre 0 y 65535

veamos como ejemplo directamente un programa en Pascal
program tipos(output);
var ashor, negashor: shortint;
ainte, negainte: integer;
along, negalong: longint;
abyte, negabyte: byte;
aword, negaword: word;
rta:char;
begin ashor:= 123; negashor:= -123;
ainte:= 12345; negainte:= -12345;
along:= 1234567890; negalong:= -1234567890;
abyte:= 234; negabyte:= -1 * abyte; Pascal no acepta una asignacin
aword:= 65432; negaword:= -1 * aword; directa fuera del rango
writeln('Tipo shortint ',ashor, ' ', negashor);
writeln('Tipo integer ',ainte, ' ', negainte);
writeln('Tipo longint ',along, ' ', negalong);
writeln('Tipo byte ',abyte, ' ', negabyte);
writeln('Tipo word ',aword, ' ', negaword);
write('Fin, pulse...');
Algoritmos y Estructuras de Datos
7
read(rta)
end.

y la salida que genera este programa es

Tipo shortint 123 -123
Tipo integer 12345 -12345
Tipo longint 1234567890 -1234567890
Tipo byte 234 22 este valor (22) y el valor siguiente (104) se deben a que al calcular el
Tipo word 65432 104 producto por -1 nos salimos fuera del rango, hecho que no poda prever
Fin, pulse... el compilador, podemos pensar que los domicilios de las variables
rebalsaron, produciendo un resultado inesperado. Lo mismo pudo
haber ocurrido con los otros tipos.





Escalares:

Son aquellos que no tienen ninguna estructura
Standard: No necesitan ser declarados. Los reconoce Pascal directamente
Declarados: Pascal permite al programador definir tipos especiales de datos.
Son reconocidos nicamente dentro del mdulo donde fueron creados


Escalares declarados:

El programador puede inventar datos a los efectos de su programa, este nuevo tipo de dato
nace y muere en ese mdulo. Por ejemplo
. . . . .
type diasem = (lun, mar, mie, jue, vie, sab, dom);
var x, y : diasem;
. . . . .
a partir de este momento, el programa reconocer adems de los tipos de datos Standard, el tipo
diasem, un nuevo tipo escalar en el cual la relacin de orden la da el orden en que fueron
definidos.

vale la relacin como en los Standard vie<dom , sab>lun , etc.
pueden hacerse asignaciones x := vie , y := lun y por ejemplo
x <= y devolver como resultado false
x > mar devolver como resultado true


Tipo subrango:

Son subconjuntos de los escalares. Se pueden crear subrangos de cualquier escalar, excepto real
[17 . . 25] [j . . p] [mar . . sab]



Estructurados:

Tienen una cierta estructura u orden y los veremos en su momento.
Algoritmos y Estructuras de Datos
8




Estructura de un programa Pascal:

Un programa Pascal puede constar de siete partes, de las cuales slo la primera y la ltima son
obligatorias.

1 Encabezamiento
2 Parte de declaracin de rtulos
3 Parte de definicin de constantes
4 Parte de definicin de tipos
5 Parte de declaracin de variables
6 Parte de declaracin de procedimientos y funciones
7 Parte de sentencias

Encabezamiento:

Da al programa su nombre y lista los parmetros a travs de los cuales el programa se
comunicar con su entorno.


Declaracin de rtulos:

Se puede marcar cualquier sentencia de un programa anteponindole un rtulo seguido del
carcter : (de esta manera podemos referenciarla desde la sentencia goto, pero a esta
sentencia evitaremos usarla, por lo menos al principio del aprendizaje). Los rtulos deben ser
declarados en esta seccin, la que comienza con la palabra label.


Definicin de constantes:

Sirve para introducir un identificador como sinnimo de una constante. Esta seccin comienza con
la palabra const.


Definicin de tipos:

Un tipo de datos puede ser descrito directamente en la declaracin de la variable, o referido
mediante un identificador de tipo en esta seccin, la que comienza con la palabra type.


Declaracin de variables:

Toda variable que aparezca en el programa, debe ser declarada en esta seccin. Esta seccin
comienza con la palabra var.


Declaracin de procedimientos y funciones: Todo procedimiento o funcin debe definirse en esta
seccin, no comienza con ninguna palabra en especial, sino que el encabezamiento de cada
funcin o procedimiento es lo que indica de que tipo de subprograma se trata.

Algoritmos y Estructuras de Datos
9



Sintaxis del Pascal:

La sintaxis est definida en los Diagramas Sintcticos que son entregados al alumno
oportunamente.


Nuestros algoritmos sern representados en diagramas de Chapin utilizando una manera grfica
con algunas estructuras que son las que detallamos a continuacin


Algoritmos y Estructuras de Datos
10
Estructuras de control

simple ( o de tipo si o if )
de seleccin
mltiple ( o de tipo segun o case )

estructuras de control

de tipo para ( o for )
de repeticin de tipo mientras ( o while )
de tipo repetir-hasta que ( o repeat-until )


Estructura de seleccin simple: o de tipo si o if. Permite seleccionar uno de entre dos posibles
caminos segn sea el valor de una condicin.

En Chapin la representamos as

. donde:

cond=V cond cond=F cond: es una expresin booleana, es decir
. algo que puede ser verdadero o falso
V F
. Bloque1: es un conjunto de una o mas acciones

. Bloque2: es un conjunto de cero o mas acciones
Bloque1 Bloque2

. funciona de la siguiente manera: se ingresa al bloque,
. se evala la condicin, si es Verdadera, se ejecuta el
. Bloque1 y se abandona la estructura, si es Falsa, se
ejecuta el Bloque2 y se abandona la estructura.

No hay restricciones para las estructuras que conforman los bloques, pueden contener otros si o cualquier otra
estructura que definamos de aqu en mas.

Problema: Leer los tres coeficientes a (distinto de cero), b, c, de una ecuacin de segundo grado
y resolverla en el campo real.


leer a , b , c

delta b
2
- 4 . a . c


delta >= 0
V F

x
1
= ( -b - delta ) / ( 2 . a )

x
2
= ( -b + delta ) / ( 2 . a ) escribir No hay solucin

escribir x
1
, x
2


Algoritmos y Estructuras de Datos
11
y en Pascal

program ecua (input,output) ;
var a , b , c , delta , x1 , x2 : real ;
begin read ( a , b , c ) ;
delta := b * b 4 * a * c ;
if delta >= 0 then begin x1 := ( -b sqrt(delta) ) / ( 2 * a ) ;
x2 := ( -b + sqrt(delta) ) / ( 2 * a ) ;
write ( x1 , x2 )
end
else write ( No hay solucion )
end .

supongamos que deseamos distinguir el caso de races reales y distintas del de raiz doble.
Tenemos que poner una estructura si dentro de otra si.


leer a , b , c

delta b
2
- 4 . a . c


delta >= 0
V F

V delta > 0 F

x
1
=(-b - delta)/(2.a) xd = -b / (2.a) escribir

x
2
=(-b + delta)/(2.a) escribir No hay solucin
Raiz doble ,
escribir x
1
, x
2
xd


y en Pascal

program ecua2 (input,output);
var a, b, c, delta, x1, x2, xd : real ;
begin read( a, b, c);
delta := b*b 4*a*c;
if delta >= 0 then
if delta > 0 then begin x1 := (-b sqrt(delta)) / (2*a) ;
x2 := (-b + sqrt(delta)) / (2*a) ;
write (x1, x2)
end
else begin xd := -b / (2*a);
write (Raiz doble, xd)
end
else write ( No hay solucion )
end .




Algoritmos y Estructuras de Datos
12


A continuacin plantearemos un problema y veremos como generalmente, para un mismo
problema puede haber varios algoritmos que lo solucionen, y tal vez todos medianamente
eficientes (el alumno puede omitir esta porcin del apunte entre los smbolos )



Problema: Leer tres letras maysculas e imprimirlas ordenadas (clasificadas) alfabticamente.
(llamaremos c1 , c2 , c3 a las variables que contendrn estas letras maysculas)

Mtodo 1 : Primero vemos si la menor es c1, si es as vemos entre c2 y c3 cual es menor e
imprimimos en consecuencia si no es as, vemos si la menor es c2 y en caso afirmativo
comparamos c1 con c3 e imprimimos en consecuencia, en caso de que tambin esto sea falso,
evidentemente la menor es c3, comparamos c1 con c2 e imprimimos segn corresponda.


c1 , c2 , c3 E

(A1)
c1 < c2 y c1 < c3
V F

(A2) (A3)
c2 < c3 c2 < c3
V F V F


S S (A4) (A5)
c1 < c3 c1 < c2
V F V F
c1,c2,c3 c1,c3,c2
S S S S

c2,c1,c3 c2,c3,c1 c3,c1,c2 c3,c2,c1


program clasifica3(input,output);
var c1,c2,c3:char;
begin
read(c1,c2,c3);
if c1<c2 and c1<c3 then if c2<c3 then write(c1,c2,c3)
else write(c1,c3,c2)
else if c2<c3 then if c1<c3 then write(c2,c1,c3)
else write(c2,c3,c1)
else if c1<c2 then write(c3,c1,c2)
else write(c3,c2,c1)
end.

La anterior tal vez sea la forma mas ortodoxa de resolver el problema. Veamos otra
Algoritmos y Estructuras de Datos
13


Mtodo 2 : Otra forma sera poner tres IF, uno a continuacin de otro buscando cual es el menor
de los tres caracteres (sin poner nada en la bifurcacin por FALSO), de esta manera uno de los
tres tomar la situacin y a los otros se los pasar de largo. Despus, ya dentro del IF
correspondiente se buscar cual de los restantes dos caracteres es el menor, y se imprimir en
consecuencia. Tal vez esta otra solucin sea mas fcil de comprender. Vemosla

E
c1 , c2 , c3
(B1)
c1 < c2 y c1 < c3
V F

(B2)
c2 < c3
V F

S S
c1 , c2 , c3 c1 , c3 , c2

(B3)
c2 < c1 y c2 < c3
V F

(B4)
c1 < c3
V F

S S
c2 , c1 , c3 c2 , c3 , c1

(B5)
c3 < c1 y c3 < c2
V F

(B6)
c1 < c2
V F

S S
c3 , c1 , c2 c3 , c2 , c1


program clasifica3bis(input,output);
var c1,c2,c3:char;
begin read(c1,c2,c3);
if c1<c2 and c1<c3 then if c2<c3 then write(c1,c2,c3)
else write(c1,c3,c2);
if c2<c1 and c2<c3 then if c1<c3 then write(c2,c1,c3)
else write(c2,c3,c1);
if c3<c1 and c3<c2 then if c1<c2 then write(c3,c1,c2)
else write(c3,c2,c1)
end.
Algoritmos y Estructuras de Datos
14

Comparemos ambas soluciones. Si bien la segunda es mas clara para leer (tanto el Chapin
como el Pascal), es menos eficiente. Veamos por que:



Supongamos que los tres caracteres sean D , P y H, es decir c1=D , c2=P y c3=H,

En el primer algoritmo, se ejecutara el IF (A1), luego el IF (A2), luego un WRITE y se
terminara el algoritmo.

En cambio, en el segundo algoritmo, se ejecutara el IF (B1), luego el IF (B2), luego un
WRITE, luego el IF (B3), luego el IF (B5),y se terminara el algoritmo. Hemos realizado en el
segundo algoritmo dos IFs de mas.



Supongamos que los tres caracteres sean M , B y W, es decir c1=M , c2=B y c3=W,

En el primer algoritmo, se ejecutara el IF (A1), luego el IF (A3), luego el IF (A4), luego un
WRITE y se terminara el algoritmo.

En cambio, en el segundo algoritmo, se ejecutara el IF (B1), luego el IF (B3), luego el IF
(B4), luego un WRITE, luego el IF (B5),y se terminara el algoritmo. Hemos realizado en el
segundo algoritmo un IF de mas.



Si el juego de tres caracteres es Z , F y M, es decir c1=Z , c2=F y c3=M, no hay
diferencia en cuanto a ambos algoritmos (queda para el alumno la verificacin).



De todos modos, ya que no conocemos el juego de datos que entrar, concluimos que el primer
algoritmo es mas eficiente.


Pero tenemos otra posibilidad de resolver el problema que tal vez no sea la primer forma que
nos viene a la mente al intentar el algoritmo, pero que tal vez sea tanto o mas eficiente que la
primera



Mtodo 3 : Leamos las tres letras e intercambiemos para dejar la menor en c1. Para esto
comparo c1 con c2 y si c1 es mayor que c2 las intercambio mediante un valor auxiliar. En c1
qued la menor de esas dos. Luego comparo c1 con c3 y hago lo mismo que en el caso anterior.
Estoy seguro que en c1 est la letra mas chica de las tres. Luego simplemente comparo c2 con c3
e imprimo en consecuencia.

Pongamos este mtodo en Chapin y Pascal

Algoritmos y Estructuras de Datos
15


E program clasifica3tres(input, output) ;
c1 , c2 , c3 var c1 , c2 , c3 : char ;
begin if c1>c2 then begin aux := c1 ;
c1 > c2 c1 := c2 ;
V F c2 := aux
aux c1 end ;
if c1>c3 then begin aux := c1 ;
c1 c2 c1 := c3 ;
c3 := aux
c2 aux end
if c2<c3 then write(c1,c2,c3)
else write(c1,c3,c2)
c1 > c3 end.
V F
aux c1

c1 c3

c3 aux

c2 < c3
V F
E E

c1,c2,c3 c1,c3,c2



Por si desean probarlos en la computadora hemos juntado los tres mtodos en un solo programa
y ejecutamos cada uno para las seis posibilidades de orden en que hubiesen podido entrar, y en
vez de leer las ternas seis veces, las hemos asignado utilizando un case (se ver en el punto
siguiente), formando las seis permutaciones posibles. Hemos supuesto que las tres letras a
comparar son P Q R.
Las seis posibilidades son PQR , PRQ , QPR , QRP , RPQ y RQP


program TresOrd3(output);
var c1, c2, c3, rta, aux: char; h, m, s, hund: word; indi: integer;
begin
for indi:=1 to 6 do
begin
case indi of
1: begin c1 := 'P' ; c2 := 'Q' ; c3 := 'R' end ;
2: begin c1 := 'P' ; c2 := 'R' ; c3 := 'Q' end ;
3: begin c1 := 'Q' ; c2 := 'P' ; c3 := 'R' end ;
4: begin c1 := 'Q' ; c2 := 'R' ; c3 := 'P' end ;
5: begin c1 := 'R' ; c2 := 'P' ; c3 := 'Q' end ;
6: begin c1 := 'R' ; c2 := 'Q' ; c3 := 'P' end
end;
write('Metodo 1 - ',c1,c2,c3,' ');
if ((c1<c2) and (c1<c3)) then
if c2<c3 then writeln(c1,c2,c3)
Algoritmos y Estructuras de Datos
16
else writeln(c1,c3,c2)
else if ((c2<c1) and (c2<c3)) then
if c1<c3 then writeln(c2,c1,c3)
else writeln(c2,c3,c1)
else
if c1<c2 then writeln(c3,c1,c2)
else writeln(c3,c2,c1)
end; writeln;
for indi:=1 to 6 do
begin
case indi of
1: begin c1 := 'P' ; c2 := 'Q' ; c3 := 'R' end ;
2: begin c1 := 'P' ; c2 := 'R' ; c3 := 'Q' end ;
3: begin c1 := 'Q' ; c2 := 'P' ; c3 := 'R' end ;
4: begin c1 := 'Q' ; c2 := 'R' ; c3 := 'P' end ;
5: begin c1 := 'R' ; c2 := 'P' ; c3 := 'Q' end ;
6: begin c1 := 'R' ; c2 := 'Q' ; c3 := 'P' end
end;
write('Metodo 2 - ',c1,c2,c3,' ');
if ((c1<c2) and (c1<c3)) then if c2<c3 then writeln(c1,c2,c3)
else writeln(c1,c3,c2);
if ((c2<c1) and (c2<c3)) then if c1<c3 then writeln(c2,c1,c3)
else writeln(c2,c3,c1);
if ((c3<c1) and (c3<c2)) then if c1<c2 then writeln(c3,c1,c2)
else writeln(c3,c2,c1);
end; writeln;
for indi:=1 to 6 do
begin
case indi of
1: begin c1 := 'P' ; c2 := 'Q' ; c3 := 'R' end ;
2: begin c1 := 'P' ; c2 := 'R' ; c3 := 'Q' end ;
3: begin c1 := 'Q' ; c2 := 'P' ; c3 := 'R' end ;
4: begin c1 := 'Q' ; c2 := 'R' ; c3 := 'P' end ;
5: begin c1 := 'R' ; c2 := 'P' ; c3 := 'Q' end ;
6: begin c1 := 'R' ; c2 := 'Q' ; c3 := 'P' end
end;
write('Metodo 3 - ',c1,c2,c3,' ');
if c2<c1 then begin aux:=c1 ; c1:=c2 ; c2:=aux end;
if c3<c1 then begin aux:=c1 ; c1:=c3 ; c3:=aux end;
if c2<c3 then writeln(c1,c2,c3)
else writeln(c1,c3,c2)
end;
write('Pulse una tecla . . .'); read(rta)
end.



Algoritmos y Estructuras de Datos
17

Estructura de Seleccin Mltiple: (o de tipo CASE, o SEGN SEA) Permiten seleccionar uno de
entre varios caminos

Esta estructura es la que mas difiere con las implementaciones en un Lenguaje u otro.


Se usa principalmente cuando debe armarse un men de opciones de la forma:

Qu tarea desea hacer ?
1 Altas
2 Bajas
3 Modificaciones
4 Listados
5 Terminar

Elija su opcin:



La simbolizaremos as
(las flechas en verde son para el ejemplo posterior)




selector

. s
1
, s
2
, s
j
, s
k
, s
n
, s
p
. . . . . . . . .
. s
v
, s
w
,


. Bloque1 Bloque2 Bloque3 . . . . . . . . . BloqueN






donde:

selector: es una variable simple de cualquier tipo, excepto real (la mayora de las veces de tipo integer)

s
1
, s
2
, s
w
son constantes, del mismo tipo que el selector


funciona de la siguiente manera: se ingresa a la estructura, se evala el selector, se busca ese valor dentro de las
constantes s
i
y se ejecuta el bloque de la columna donde aparezca.
No hay restricciones para las estructuras que conforman los bloques, pueden contener otros segun o si o cualquier
otra estructura que definamos de aqu en mas.

ejemplifiquemos: supongamos que ingresamos a la estructura, evaluamos el selector y su valor es s
k
, ejecutamos
el Bloque2 y salimos de la estructura.



Algoritmos y Estructuras de Datos
18

Problema: Leer dos nmeros reales (el segundo distinto de cero) y efectuar una operacin (suma,
resta, multiplicacin o divisin) segn un men de opciones.


escribir Ingrese dos reales
leer a , b

escribir Qu operacin desea efectuar?
1 Sumarlos
2 Restarlos
3 Multiplicarlos
4 Dividirlos
Ingrese su opcin:

leer op

op


1 2 3 4

r = a + b r = a b r = a . b r = a / b

escribir El resultado es , r

program operacin (input , output) ;
var a , b , r : real ; op : integer ;
begin write (Ingrese dos reales) ;
read ( a , b );
writeln ;
writeln (Que operacin desea efectuar?) ;
writeln (1 Sumarlos) ;
writeln (2 Restarlos) ;
writeln (3 Multiplicarlos) ;
writeln (4 Dividirlos) ;
write (Ingrese su opcin:) ;
read ( op ) ;
case op of 1 : r := a + b ;
2 : r := a - b ;
3 : r := a * b ;
4 : r := a / b
end ;
write (El resultado es , r )
end.


Algoritmos y Estructuras de Datos
19

Estructura de repeticin de tipo para: o de tipo for. Permite repetir un bloque de sentencias un
nmero conocido de veces

. donde:

para indi de vi vf indi: es una variable simple de cualquier tipo
. (excepto real)

. indi=vi vi y vf son expresiones del mismo tipo que indi

. indi=vi+1 Bloque: es un conjunto de una o mas acciones
Bloque

. indi=vi+2 indi=vf funciona de la siguiente manera: (lo explicaremos
. para el caso en que indi , vi , vf sean tipo integer)
. Se ingresa a la estructura, se recorre el Bloque
por primera vez con un valor de indi igual a vi. Se
salta nuevamente a la cabecera y se recorre nueva-
mente el bloque con indi=vi+1, y as sucesivamente
hasta recorrerlo por ltima vez con indi=vf.
No hay restricciones para las estructuras que conforman el bloque, pueden contener otros para o segn o si o
cualquier otra estructura que definamos de aqu en mas.
Tenemos que hacer varias observaciones:
- si indi, vi, vf fuesen char en vez de indi=vi+1 tendramos que decir indi=el sucesor de vi, etc.
- si al intentar ingresar a la estructura fuese vi>vf, se salta la estructura y el bloque no se ejecuta
nunca
- Pascal no tiene incremento, es decir que el valor del ndice siempre ser el siguiente (si se
desea un escaln hay que programarlo dentro del bloque)

Pascal tiene el para descendente y en Chapin lo indicaremos con en vez de . El ndice, en vez
de ir creciendo va decreciendo y en cuanto a las observaciones, son anlogas.

Problema: Calcular la suma de los nmeros enteros entre 27 y 145 (ambos incluidos).
(aclaramos que se puede calcular mediante una simple frmula, pero vamos a usar un para)

tot 0

para i de 27 145

tot tot + i

escribir Suma vale , tot

program unasuma (input , output) ;
var tot , i : integer ;
begin tot := 0 ;
for i := 27 to 145 do tot := tot + i ;
write (Suma vale , tot)
end.

hacemos notar que dentro del Bloque hemos usado el ndice del para. Veamos un ejemplo donde
no se usa, simplemente funciona como un contador.

Algoritmos y Estructuras de Datos
20

Problema: Leer los tres coeficientes a (distinto de cero), b, c, de diez ecuaciones de segundo
grado e ir resolvindolas en el campo real a medida que se lee cada terna.

para i de 1 10

leer a , b , c

delta b
2
- 4 . a . c


delta >= 0
V F

x
1
= ( -b - delta ) / ( 2 . a )

x
2
= ( -b + delta ) / ( 2 . a ) escribir No hay solucin

escribir x
1
, x
2


program ecuas (input,output) ;
var a , b , c , delta , x1 , x2 : real ;
i : integer ;
begin for i:=1 to 10 do begin
readln(a,b,c);
delta := b*b 4*a*c;
if delta >= 0 then
begin x1 := (-b sqrt(delta))/(2*a);
x2 := (-b + sqrt(delta))/(2*a);
writeln(x1,x2)
end
else
write ( No hay solucion )
end
end .

Estructura de repeticin de tipo mientras: o de tipo while. Permite repetir un bloque de sentencias
un cierto nmero de veces lo que depende del resultado de una condicin.
. donde:

mientras cond cond: es una expresin booleana
. cond=V cond=V cond=V cond=F

.

. Bloque: es un conjunto de una o mas acciones
Bloque

. funciona de la siguiente manera: ingresamos a la
. estructura, evaluamos la condicin, si es verdadera
. se recorre el Bloque; se salta a la cabecera, se vuel-
ve a recorrer el Bloque; y as sucesivamente, mien-
tras la condicin sea verdadera. Cuando al volver a
la cabecera, la condicin es falsa, se abandona la
Algoritmos y Estructuras de Datos
21
estructura sin recorrer el Bloque. Si al intentar ingresar por primera vez a la estructura, la condicin es falsa, se sale
de la misma sin ejecutar el bloque. Conclusin: en el mientras podra ocurrir que el bloque no se ejecute nunca.

Problema: Leer los tres coeficientes a (distinto de cero), b, c, de varias ecuaciones de segundo
grado (no se sabe cuantas) e ir resolvindolas en el campo real a medida que se lee cada terna.

Ac se nos presenta un problema muy comn en algoritmia, tenemos que reiterar un cierto
conjunto de acciones pero no se sabe cuantas veces, no vamos a usar un para ya que este lo
usaremos cuando al ingresar a la estructura se conoce la cantidad de veces que se debe repetir el
Bloque. Usaremos un mientras, pero ahora la cuestin es como indicamos el fin de la repeticin.
Esto se consigue mediante un hecho (una lectura, un clculo,.) que no pueda ser interpretado
como un dato, sino como una seal de fin de entrada de los mismos. En este ejemplo ser
ingresando un valor de cero para a

.
leer a

mientras a <> 0

leer b , c

delta b
2
- 4 . a . c


delta >= 0
V F

x
1
= ( -b - delta ) / ( 2 . a )

x
2
= ( -b + delta ) / ( 2 . a ) escribir No hay solucin

escribir x
1
, x
2

leer a


program ecuas2 (input,output) ;
var a , b , c , delta , x1 , x2 : real ;
begin read(a) ; while a<>0 do begin
readln(b,c);
delta := b*b 4*a*c;
if delta >= 0 then
begin x1 := (-b sqrt(delta))/(2*a);
x2 := (-b + sqrt(delta))/(2*a);
writeln(x1,x2)
end
else
writeln ( No hay solucion )
read(a)
end
end .



Algoritmos y Estructuras de Datos
22

Estructura de repeticin de tipo repetir: o de tipo repeat. Permite repetir un bloque de sentencias
un cierto nmero de veces que depende del resultado de una condicin.


donde:



cond: es una expresin booleana
Bloque
funciona de la siguiente manera: ingresamos a la
. estructura, recorremos el Bloque (siempre recorre-
. mos el Bloque por lo menos una primera vez); eva-
. luamos la condicin, si es falsa, saltamos al comien
cond=F cond=F cond=F cond=V zo del Bloque y volvemos a recorrerlo; y as suce-
hasta que cond vivamente hasta que la condicin sea verdadera.
. Cuando la condicin es verdadera, se abandona la
. estructura.

Esta estructura tambin la podemos usar cuando al ingresar a la misma, no se sabe la cantidad
de veces que debe repetirse el Bloque. Presta una utilidad muy similar al mientras, tan es as que
hay lenguajes que no la tienen implementada. Sin embargo, conceptualmente es opuesta al
mientras, ya que en el mientras, se ejecuta el Bloque mientras la condicin es verdadera, y se
abandona la estructura en el momento que la condicin se hace falsa. En el repetir, en cambio, el
Bloque se ejecuta en tanto y en cuanto la condicin sea falsa, y se abandona la estructura cuando
la condicin se hace verdadera.
Otra diferencia, es que en el repetir como acabamos de ver, el Bloque se ejecuta por lo menos
una vez, en cambio en el mientras, podra no ejecutarse nunca.
Problema: Leer los tres coeficientes a (distinto de cero), b, c, de varias ecuaciones de segundo
grado (no se sabe cuantas, pero por lo menos una) e ir resolvindolas en el campo real a medida
que se lee cada terna.
Nuevamente usaremos como valor de corte a = 0.


leer a

leer b , c
delta b
2
- 4 . a . c


delta >= 0
V F

x
1
( -b - delta ) / ( 2 . a )

x
2
( -b + delta ) / ( 2 . a ) escribir No hay solucin

escribir x
1
, x
2

leer a

hasta que a = 0

Algoritmos y Estructuras de Datos
23

program ecuas3 (input,output);
var a, b, c, x1, x2, delta : real ;
begin read( a ) ;
repeat read( b, c ) ;
delta := b*b 4*a*c ;
if delta >= 0 then begin x1 := (-b sqrt(delta))/(2*a);
x2 := (-b + sqrt(delta))/(2*a);
write(x1,x2)
end
else write (No hay solucin);
read( a )
until a = 0
end.

Vale la pena hacer notar que hemos resuelto el mismo problema con un mientras y con un
repetir, pero la condicin fue exactamente una contraria a la otra.



Validacin de una entrada:

Supongamos que queremos leer un entero que debe ser mayor o igual que 7 y menor o igual que
15. Lo haremos con un mientras y con un repetir

con while con repeat
. .
. .
write(Ingrese un entero entre 7 y 15) ; .
read( n ) ; repeat write(Ingrese un entero entre 7 y 15) ;
while n < 7 or n > 15 do read( n )
begin write(Error, ingrese de nuevo) ; until n >= 7 and n <= 15;
read( n ) .
end ; .
. .
. .
Ambas funcionan bien, pero con el while resulta mas amigable.
Notar nuevamente que las condiciones son opuestas.
Algoritmos y Estructuras de Datos
24
Tipo Array (Arreglos):

Es un tipo de dato estructurado. Permite agrupar en una entidad varios datos. Tiene las siguientes
caractersticas:
- Tienen tamao fijo
- Todos sus elementos son del mismo tipo
- El tipo de sus elementos puede ser cualquiera (real, string, otro array, record.)
- Estn ubicados en la memoria principal

Un tipo de arreglo son nuestros conocidos, vectores y matrices
Los elementos del arreglo son referenciados a travs de ndices de manera unvoca

arreglo bidimensional de quince
arreglo unidimensional elementos reales, organizado en
de seis elementos enteros cinco filas y tres columnas

61 -0.18 12.0 2.5
-3 17.1 -14.2539 6.44
v = 17 m = 3.46 2.5 -9.0
12 22.53 14.1 22.12
-3 10.7 -3.91 11.1
0
v [ 5 ] m [ 4 , 3 ]

hemos adoptado esa forma de visualizarlos, para seguir lo que se realiza en Algebra, pero bien
pudimos haberlos dibujado de otra, por ejemplo a v horizontal.
Los arreglos de mas de dos dimensiones, resultan algo mas difcil de visualizar, pero eso se va
adquiriendo con la prctica.

Problema: Leer dos arreglos unidimensionales a y b de 5 elementos reales cada uno. Calcular la
suma del producto de sus elementos de igual posicin e informarlo.
(ac deberamos aclarar en el enunciado si se lee primero a y luego b, o si leeremos a
1
y b
1
,
luego a
2
y b
2
, etc. Supongamos que leemos primero a y luego b)

program dosarre(input,output); para i de 1 5
type v5=array[1..5]of real; leer a
i
var suma:real; a,b:v5; i:integer;
begin for i:=1 to 5 do read(a[i]); para i de 1 5
for i:=1 to 5 do read(b[i]); leer b
i

suma:=0;
for i:=1 to 5 do suma 0
suma:=suma+a[i]*b[i];
write(Suma vale,suma) para i de 1 5
end. suma suma + a
i
. b
i


escribir Suma vale, suma


pudimos haber evitado la declaracin de tipo type simplemente declarando los arreglos en la seccin var.
program dosarre(input,output);
var suma:real; a,b:array[1..5]of real; i:integer;
. . . .


Algoritmos y Estructuras de Datos
25
Problema: Leer por filas un arreglo entero bi-dimensional de cuatro filas y tres columnas y armar
un arreglo unidimensional con la suma de los elementos de cada fila y otro con la suma de los
elementos de cada columna. Mostrar los resultados
(agregamos un ejemplo numrico para ayudar a comprender el enunciado)


-3 12 0 9
x = 9 0 17 sumf = 26
12 9 -2 19
-2 6 9 13

sumc = [ 16 27 24 ]

para i de 1 4


para j de 1 3

leer x
i j


para i de 1 4

sf 0

para j de 1 3

sf sf + x
i j


sumf
i
sf

para j de 1 3

sc 0

para i de 1 4

sc sc + x
i j


sumc
j
sc
escribir Vector suma de filas

para i de 1 4

escribir sumf
i


escribir Vector suma de columnas

para j de 1 3

escribir sumc
j


program sumaele(input,output);
var i, j, sf, sc: integer; sumf: array[1..4]of integer;
x: array[1..4,1..3]of integer; sumc: array[1..3] of integer;
Algoritmos y Estructuras de Datos
26
begin for i:= 1 to 4 do for j:= 1 to 3 do read(x[i,j]);
for i:= 1 to 4 do begin sf:=0;
for j:= 1 to 3 do sf:= sf + x[i,j];
sumf[i]:= sf
end;
for j:= 1 to 3 do begin sc:=0;
for i:= 1 to 4 do sc:= sc + x[i,j];
sumc[j]:= sc
end;
write(Vector suma de filas);
for i:= 1 to 4 do write(sumf[i]);
write(Vector suma de columnas);
for j:= 1 to 3 do write(sumc[j])
end.


Los indices de los arreglos son tipo subrango. Una matriz puede tener un ndice subrango de un
tipo, y otro ndice subrango de otro tipo.

Problema: Una escuela tiene siete grados (numerados del 1 al 7), de cada uno de los cuales hay
cuatro divisiones (d, e, f, g) y se desea analizar para los grados 3, 4, 5, 6 y 7 las
cantidades de alumnos que concurren a cada uno de esos 20 grados. Leer por grado la cantidad
de alumnos de cada uno de los veinte grados e informar cual es el grado y divisin que tiene mas
alumnos (se supone que es uno solo).

Supongamos que los datos entran as:

div. d div. e div. f div. g
grado 3 35 32 29 30
grado 4 31 28 33 36
grado 5 27 39 25 32
grado 6 30 31 33 34
grado 7 29 35 35 28

y la respuesta del algoritmo debera ser

Con 39 alumnos 5e es el mayor

program escuela (input,output);
var escu: array[3..7,d..g] of integer;
i, gradomax, maxalu: integer; j, divmax: char;
begin for i:=3 to 7 do for j:= d to g do read(escu[i, j]);
gradomax:=3; divmax:=d; maxalu:=escu[3,d];
for i:=3 to 7 do for j:= d to g do
if escu[i, j]>maxalu then begin gradomax:=i;
divmax:=j;
maxalu:=escu[i,j]
end;
write(Con,maxalu, alumnos ,gradomax,divimax, es el mayor)
end.


Problema: Un sanatorio desea analizar la cantidad de casos de gripe atendidos determinados
das segn la temperatura mnima del da.
Algoritmos y Estructuras de Datos
27

A tal efecto desea totalizar los casos atendidos en los 3 ltimos aos (slo interesa analizar
temperaturas mnimas del da entre -5 y 12 grados). (18 temperaturas mnimas distintas)
Construir un algoritmo para leer y totalizar esos datos y luego informarlos. Finalmente, ingresando
una temperatura mnima (entre -5 y 12 grados), informar la cantidad total de casos atendidos en
das con esa temperatura mnima.

program sanatorio (input,output);
var casos: array[-5..12] of integer; te, i, cantcasos: integer;
begin
for i:= -5 to 12 do casos[i]:= 0;
write(Ingrese mnima del da, fuera de rango termina);
read(te);
while te>=-5 and te<=12 do
begin write( y ahora la cantidad de casos), readln(cantcasos);
casos[te]:= casos[te] + cantcasos;
write(Ingrese mnima del da, fuera de rango termina);
read(te)
end;
writeln;
writeln(Cantidad de casos totalizados por temperatura mnima);
writeln(----------------------------------------------------);
for i:=-5 to 12 do writeln( i, casos[i] );
write(Ingrese una temperatura dentro del rango); read(te);
write(La cantidad total de casos para esa mnima es; casos[te])
end.
Algoritmos y Estructuras de Datos
28

CLASIFICACION (ORDENAMIENTO), BUSQUEDA E INTERCALACION

Trabajando con arreglos unidimensionales, surgen inmediatamente tres tareas tpicas:
clasificacin (ordenamiento), bsqueda e intercalacin.

Clasificacin (Ordenamiento): Dado un arreglo, clasificar (reordenar) sus elementos de modo que
queden en forma creciente (o decreciente).

Bsqueda: Dado un arreglo, determinar si un cierto dato se encuentra o no dentro de l.

Intercalacin: Dados dos arreglos que contengan elementos del mismo tipo, ambos clasificados
con el mismo criterio, no necesariamente ambos con la misma cantidad de elementos. Armar un
tercer arreglo que contenga los elementos de ambos y que est clasificado con el mismo criterio.
Observacin: Si bien el resultado sera el pedido, en intercalacin no consideraremos correcto
armar un arreglo con los elementos de ambos y luego clasificarlo, ya que esto implicara un
nmero mucho mayor de operaciones.


Clasificacin:

Si bien hay captulos de libros dedicados a este tema, slo veremos dos mtodos: por
intercambio (burbuja) y por seleccin del mnimo.(ejemplificaremos para clasificar de menor a mayor)

Por intercambio: Consiste en comparar el ltimo elemento del arreglo con el penltimo, si estn
en el orden buscado, se los deja as, si no, se los intercambia. Luego se compara el penltimo con
el antepenltimo, si estn en el orden buscado, se los deja as, si no, se los intercambia. Y as
sucesivamente hasta repetir lo mismo, comparando el primer elemento con el segundo. De esta
manera, nos aseguramos que en la primer posicin qued el menor o el mas liviano, elemento
que se comport como una burbuja.
Repetimos lo mismo, siempre comenzando desde el fondo del arreglo, pero esta vez llegamos
hasta la segunda posicin del arreglo. Estamos seguros que los dos mas pequeos quedaron en
las dos primeras posiciones y en orden.
Repetimos siempre lo mismo hasta la penltima posicin con lo que garantizamos que hasta la
penltima posicin quedaron en orden, y por lo tanto la ltima tambin.

Veamos un ejemplo numrico. Tratemos de clasificar el arreglo ( 8 2 0 5 1 4 )

8 8 8 8 8 0 0 0 0 0 0 0 0 0 0 0

2 2 2 2 0 8 8 8 8 1 1 1 1 1 1 1

0 0 0 0 2 2 2 2 1 8 8 8 2 2 2 2

5 5 1 1 1 1 1 1 2 2 2 2 8 8 4 4

1 1 5 5 5 5 4 4 4 4 4 4 4 4 8 5

4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 8


1ra. recorrida 3ra. recorrida 5ta. recorrida

2da. recorrida 4ta. recorrida

Algoritmos y Estructuras de Datos
29

Problema: Leer un arreglo de 10 elementos reales, clasificarlo por el mtodo de intercambio.
Imprimirlo clasificado.



para i de 1 10 podra incorporarse una verificacin
tal que si antes de completar el para
leer a
i
de mas afuera nos damos cuenta que el
arreglo YA qued clasificado, abandonemos
para i de 1 9 el proceso.

para j de 9 i

a
j
> a
j + 1

V F


aux a
j


a
j
a
j + 1


a
j + 1
aux
para i de 1 10

escribir a
i





y en Pascal



program burbuja (input,output);
var i,j:integer; aux:real; a:array[1..10]of real;
begin for i:= 1 to 10 do read(a[i]);
for i:= 1 to 9 do for j:= 9 downto i do
if a[j] > a[j+1] then begin aux:= a[j];
a[j]:=a[j+1];
a[j+1]:=aux
end;
for i:=1 to 10 do write(a[i])
end.



Por seleccin del mnimo: En un primer paso, se busca el mnimo de todos los elementos del
arreglo (memorizando valor y posicin) y se lo intercambia con el que est en la primera posicin.
Luego se vuelve a buscar el mnimo, pero buscando desde la segunda posicin en adelante y se
lo intercambia con el segundo. As sucesivamente hasta llegar al penltimo elemento.


Ejemplifiquemos sobre el mismo arreglo anterior
Algoritmos y Estructuras de Datos
30





8 0 0 0 0 0
5to. paso
2 2 1 1 1 1
4to. paso
0 8 8 2 2 2
3er. paso
5 5 5 5 4 4
2do. paso
1 1 2 8 8 5
1er. paso
4 4 4 4 5 8 necesariamente el 8 (el mayor) qued ltimo









Problema: Leer un arreglo de 10 elementos reales, clasificarlo por el mtodo de seleccin del
mnimo. Imprimirlo clasificado.

para i de 1 10

leer a
i


para i de 1 9

min a
i
; posmin i

para j de i+1 10

a
j
< min
V F

min a
j


posmin j

a
posmin
a
i
; a
i
min

para i de 1 10

escribir a
i




program porelmin(input,output);
var a : array[1..10]of real; i, j, posmin : integer; min : real;
begin for i:= 1 to 10 do read(a[i]);
for i:= 1 to 9 do
begin min:= a[i]; posmin:= i;
Algoritmos y Estructuras de Datos
31
for j:= i+1 to 10 do if a[j]<min then begin min:= a[j];
posmin:= j
end;
a[posmin]:= a[i];
a[i]:= min
end;
for i:= 1 to 10 do write([i])
end.





Bsqueda:

Consiste en lo siguiente, dado un arreglo averiguar si dentro del arreglo est, o no un determinado
elemento (que podemos llamar k).
Existen muchos mtodos de bsqueda, cada uno con diferentes variaciones. Veremos slo dos,
bsqueda secuencial y bsqueda binaria (o dicotmica). El uso de uno u otro mtodo, depende
de que el arreglo est clasificado o no.
La bsqueda binaria o dicotmica sirve si el arreglo est clasificado. Si no tenemos garanta de
que el arreglo est clasificado, no hay que usarla.
La bsqueda secuencial sirve en ambos casos, pero en arreglos clasificados, de muchos
elementos, si bien funciona, es ineficiente y no deberamos usarla.
Podemos hacer el siguiente cuadro.


Arreglo NO clasificado Arreglo clasificado
Secuencial
USAR NO USAR (ineficiente)
Binaria
NO USAR (en gral. falla) USAR

Tambin en cada uno de los mtodos podemos distinguir dos posibilidades. Que, en caso de
estar el elemento buscado tenga la posibilidad de estar mas de una vez y debamos decidir si nos
conformamos con encontrar una ocurrencia, o queramos encontrar todas.

Vale la pena hacer notar que en un arreglo clasificado, si puede haber elementos repetidos, los
repetidos deben estar todos en posiciones adyacentes.

Bsqueda secuencial: Consiste en recorrer uno a uno los elementos del arreglo (no clasificado)
y compararlos con k hasta encontrarlo o no

Para ejemplificar, supongamos que tenemos el arreglo a de 7 elementos enteros y deseamos
saber si un cierto entero k est o no dentro del arreglo, y si est, en que posicin est su primer
ocurrencia. Supongamos

16 y supongamos que k sea -4
-39 la respuesta del algoritmo debera ser no est
0
a = 25
5 si suponemos que k es 25
25 la respuesta del algoritmo debera ser est en la posicin 4
17


Algoritmos y Estructuras de Datos
32

Si nos interesa conocer todas las ocurrencias.

25 y supongamos que k sea -4
-39 la respuesta del algoritmo debera ser no est
22
a = 25
5 si suponemos que k es 22
22 la respuesta del algoritmo debera ser est en la posicin 3
17 est en la posicin 6


Veamos los algoritmos



Para el caso que interese una sola ocurrencia


Problema: Leer un arreglo de 7 elementos enteros. Leer luego un entero. Informar si este entero
est o no. Si est, informar la posicin de su primera ocurrencia.



para i de 1 7

leer a
i


leer k

i 0

i i + 1

hasta que a
i
= k o i =7


a
i
= k

V F

escribir Est en la escribir No est
posicin , i


y el programa en Pascal

program secue1(input,output);
var a: array[1..7] of integer; i, k: integer;
begin for i:= 1 to 7 do read(a[i]); read(k);
i:=0;
repeat i:=i+1 until a[i]=k or i=7 ;
if a[i]=k then write(Est en la posicin,i)
else write(No est)
end.
Algoritmos y Estructuras de Datos
33



Para el caso que interesen todas las ocurrencias


Problema: Leer un arreglo de 7 elementos enteros. Leer luego un entero. Informar si ese entero
est o no. Si est, informar la posicin de todas sus ocurrencias.




para i de 1 7

leer a
i


leer k ; esta falso

para i de 1 7

a
i
= k
V F
escribir Est en la posicin, i

esta verdadero

no esta
V F

escribir No est


program secue2(input,output);
var a: array[1..7] of integer; i, k: integer; esta: boolean;
begin for i:= 1 to 7 do read(a[i]); read(k); esta:= false;
for i:= 1 to 7 do if a[i]=k then
begin write(Est en la posicin,i);
esta:=true
end;
if not esta then write(No est)
end.



Bsqueda dicotmica: Consiste en tener dos indicadores, uno de la posicin de menor orden
(min) y otro de la posicin de mayor orden (max). Al principio uno valdr 1 y el otro N, suponiendo
que la cantidad de elementos sea N. (N=11 en los dos ejemplos que siguen).
Probamos si el elemento que est en el medio del arreglo es igual al buscado. Si es el buscado,
lo hemos encontrado y finaliza el algoritmo (suponemos que nos conformamos con una sola
ocurrencia). Si no es el buscado, nos fijamos si es mayor o menor al buscado, y como el arreglo
est clasificado, si el elemento del medio es menor, si el buscado est, est en la parte de
abajo, y nos quedamos con esa parte bajando min hasta medio, pero como ya sabamos que el
del medio no era, lo bajamos una posicin mas, es decir hacemos
min medio + 1
Algoritmos y Estructuras de Datos
34
Anlogo razonamiento si el elemento del medio es mayor.
En nuestro algoritmo si max y min son de distinta paridad, su promedio dara coma cinco lo que
est prohibido como ndice, entonces tomamos la divisin entera, es decir hacemos
medio ( min + max ) div 2
donde con div simbolizamos la divisin entera


Vamos a ejemplificar para el caso de bsqueda exitosa (el elemento buscado se encuentra en el
arreglo). Supongamos que el elemento que busco es 9 ( k = 9 )
Los elementos sombreados es porque estn descartados


min -22 min -22 -22 -22

-16 -16 -16 -16

0 medio 0 0 0
min
3 3 medio 3 3 y se en-
cuentra
9 max 9 max 9 min/max/medio 9 el valor
buscado
medio 17 17 17 17

25 25 25 25

40 40 40 40

63 63 63 63

82 82 82 82

max 94 94 94 94



Vamos a ejemplificar para el caso de bsqueda fallida (el elemento buscado NO se encuentra en
el arreglo). Supongamos que el elemento que busco es 23 ( k = 23 )


min -22 -22 -22 -22 -22

-16 -16 -16 -16 -16

0 0 0 0 0

3 3 3 3 3

9 9 9 9 9

medio 17 17 17 17 max 17
min min/me-
25 min 25 medio 25 dio/max 25 min 25

40 40 max 40 40 40

63 medio 63 63 63 63

82 82 82 82 82

max 94 max 94 94 94 94

y al quedar el mximo por encima del mnimo (max < min), se deduce que el elemento buscado no est


No vamos a tratar el caso de bsqueda de todas las ocurrencias, simplemente damos una idea.

Algoritmos y Estructuras de Datos
35

Si un arreglo clasificado tiene elementos repetidos, estarn agrupados en posiciones adyacentes.
Aplicando el algoritmo de bsqueda dicotmica, que es mucho mas rpido que el secuencial,
encontraremos uno, pero no sabemos si es el primero, el ltimo, o uno cualquiera del grupo,
hacemos lo siguiente: vamos hacia arriba hasta llegar al primer elemento del grupo igual a la
clave y luego bajamos listando las posiciones mientras los elementos sean iguales al buscado.

Problema: Leer un arreglo de 11 elementos enteros, se sabe que est clasificado en forma
creciente. Leer luego un entero. Informar si ese entero est o no. Si est, informar su posicin.
Interesa ubicar una sola ocurrencia.


para i de 1 11

leer a
i


leer k

min 1 ; max 11 ; medio (min+max) div 2

mientras a
medio
<> k y min <= max

a
medio
< k
V F

min medio + 1 max medio - 1

medio (min+max) div 2

a
medio
= k
V F

escribir Est en la escribir No est
posicin, medio




program dicoto(input,output);
var min, max, k, i, medio: integer ; a: array[1..11] of integer;
begin for i:= 1 to 11 do read(a[i]); read(k);
min:=1; max:=11; medio:= (min+max) div 2;
while a[medio]<>k and min<=max do
begin if a[medio]<k then min:= medio+1
else max:= medio-1;
medio:= (min+max) div 2
end;
if a[medio]=k then write(Est en la posicin,medio)
else write(No est)
end.




Algoritmos y Estructuras de Datos
36

Intercalacin:


Tenemos dos arreglos, ambos del mismo tipo de elementos. Ambos clasificados con el mismo
criterio (ambos en forma creciente o ambos en forma decreciente).
No necesariamente ambos con la misma cantidad de elementos. Llamemos a y b a ambos
arreglos.


Sea N la cantidad de elementos de a, y sea M la cantidad de elementos de b. Queremos armar un
nuevo arreglo c que contenga todos los elementos de a y todos los elementos de b (es decir que
tenga N+M elementos) y que est tambin clasificado con el mismo criterio.


Veamos un ejemplo


a ( N = 3 ) b ( M = 7 ) c ( 7 + 3 = 10 elementos)


9 7 7
35 20 9
47 25 20
43 25
50 35
73 43
92 47
50
73
92



(sera muy ineficiente armar un nuevo arreglo que contenga al principio los elementos de a y al
final los de b y luego clasificarlo).


Sea i el ndice con que recorremos a; j el ndice con que recorremos b y k el de c.

La idea es recorrer desde el principio los arreglos a y b, comenzamos con los ndices i, j, k en 1
comparamos a
i
con b
j
y al elemento menor lo copiamos en c
k
, incrementamos en 1 a k y al ndice
del arreglo del que hayamos copiado, as hasta agotar uno de los dos arreglos, luego ponemos
los elementos que quedaban sin colocar del otro, al final de c.



Problema: Leer un arreglo de 10 elementos reales (se sabe que ingresa clasificado en forma
creciente), leer luego un arreglo de 8 elementos reales (se sabe que ingresa clasificado en forma
creciente). Formar un arreglo que contenga todos los elementos del primero y todos los
elementos del segundo y que tambin est clasificado en forma creciente. Escribirlo



Algoritmos y Estructuras de Datos
37

para i de 1 10
leer a
i


para i de 1 8

leer b
i


i 1 ; j 1 ; k 1

mientras i <= 10 y j <= 8

a
i
<= b
j

V F

c
k
a
i
c
k
b
j


i i + 1 j j + 1

k k + 1

i > 10
V F
para m de j 8 para m de i 10

c
k
b
m
c
k
a
m


k k +1 k k +1

para i de 1 18

escribir c
i



program intercala (input, output);
var a: array[1..10] of real; b: array[1..8] of real;
c: array[1..18] of real; i, j, k, m: integer;
begin for i:=1 to 10 do read(a[i]); for i:=1 to 8 do read(b[i]);
i:= 1; j:= 1; k:= 1;
while i<=10 and j<=8 do begin if a[i]<=b[j]then begin c[k]:=a[i];
i:=i+1
end
else begin c[k]:=b[j];
j:=j+1
end;
k:=k+1
end;
if i>10 then for m:=j to 8 do begin c[k]:=b[m]; k:=k+1
end
else for m:=i to 10 do begin c[k]:=a[m]; k:=k+1
end;
for i:= 1 to 18 do write(c[i])
end.

Algoritmos y Estructuras de Datos
38


Eficiencia del algoritmo:

Por que decimos que el algoritmo que acabamos de presentar es mas eficiente que copiar a en
c y a partir de ah copiar b en c, para luego clasificar c?

En nuestro algoritmo no tenemos ningn anidamiento de estructuras de repeticin. En cambio en
los mtodos de clasificacin tenemos anidadas dos estructuras de repeticin.

Supongamos que tenemos dos para anidados. El de mas afuera que se repita 200 veces y el
interior 400 veces

para i de 1 a 200
para j de 1 a 400
sentencia esta sentencia se ejecutar 80.000 veces
finpara
finpara

Si queremos clasificar por ejemplo por intercambio un arreglo de 200 elementos tendremos dos
para anidados y si bien el para interior se ejecuta cada vez una vez menos, en promedio, las
sentencias interiores se ejecutarn unas 20.000 (200x100 aproximadamente) veces, mientras
que con el algoritmo de intercalacin no tenemos anidamiento y es mucho mas rpido.





Vamos a hacer un ejemplo para ordenar las filas de una matriz (sin desarmar las filas) de manera
que queden ordenadas segn los elementos de una determinada columna, por ejemplo la
primera.

Habamos dicho que los elementos de un array podan ser de cualquier tipo, por ejemplo otro
array. A la matriz (arreglo bidimensional de 5 x 4)

12 17 -6 9
-1 4 6 8
m = 3 14 100 40
-9 46 77 11
5 6 7 8

la podemos tambin tratar como un arreglo de 5 elementos donde cada elemento es un arreglo de
4 elementos

( 12 17 -6 9 )
( -1 4 6 8 ) con m[2] hago referencia a toda la fila
m = ( 3 14 100 40 )
( -9 46 77 11 )
( 5 6 7 8 )
y este elemento puede ser
referenciado como m[4][3]


Algoritmos y Estructuras de Datos
39
Esto, en ciertos problemas puede facilitar el tratamiento.
Supongamos que queremos reordenar las filas de esa matriz de manera que los elementos de
una columna (supongamos la primera) queden en orden creciente.

Aclaramos que la clasificacin la efectuamos por el mtodo de intercambio (o burbuja) que ya
habamos visto.

program VecDeVec(input,output);
type v4=array[1..4] of integer;
var i, j: integer; m:array[1..5] of v4; aux: v4; rta:char;
begin writeln('Ingrese la matriz por filas');
for i:=1 to 5 do
for j:=1 to 4 do read(m[i][j]);
for i:=1 to 4 do
for j:=4 downto i do if m[j][1]>m[j+1][1] then
en estas tres sentencias begin aux:= m[j];
intercambio toda la fila j m[j]:=m[j+1];
con toda la fila j + 1 m[j+1]:=aux
end;
writeln('La misma, ordenada por los elementos de la 1a. fila');
for i:=1 to 5 do begin for j:=1 to 4 do write(m[i][j]:5);
writeln
end;
write('Pulse...'); read(rta)
end.

se puede probar este programa y si se ingresa

12 17 -6 9
-1 4 6 8
3 14 100 40
-9 46 77 11
5 6 7 8

la salida ser

-9 46 77 11
-1 4 6 8
3 14 100 40
5 6 7 8
12 17 -6 9










Algoritmos y Estructuras de Datos
40
SUBALGORITMOS:

Cuando tenemos que disear un algoritmo de relativa importancia en cuanto a su complejidad, es
conveniente dividirlo en partes, o mdulos, o subalgoritmos. Si a su vez, a algunos de esos
mdulos los volvemos a dividir para reducir su complejidad, tenemos un esquema como el
siguiente









. . . . . . . . .

. . . . . . . . . . . . . . . . . .

. . . . . . . . .





Hemos hecho lo que llamamos refinamientos sucesivos o tambin anlisis top-down.
(existe otra forma de componer algoritmos y es la bottom-up pero no la vamos a utilizar en este
curso).

Los subalgoritmos (o subprogramas) son los que permiten aplicar esta idea de los refinamientos
sucesivos.

Los subalgoritmos tienen otra importante utilidad y es que pueden desarrollarse con parmetros
genricos y luego utilizarse varias veces con diferentes juegos de datos.
Los parmetros de los subalgoritmos pueden ser de cualquier tipo.


Presentaremos dos tipos de subalgoritmos: las funciones y los procedimientos.


Funciones:

Tienen un uso similar a las funciones internas, pero ac, los clculos los define el programador.
Tienen todas las caractersticas de los programas, con la diferencia que no pueden ejecutarse
sueltas, sino que se ejecutan cuando son utilizadas (o llamadas) por el programa principal u otro
subprograma. Esta utilizacin puede ser a la derecha en una sentencia de asignacin, en una
condicin (de un if, un while o un repeat), en un for o incluso en una expresin en un write.

Las funciones (como las funciones internas) devuelven un nico valor a travs de su nombre, no
devuelven resultados a travs de sus parmetros.
(al final del captulo haremos un comentario sobre el verdadero funcionamiento de las funciones)

Veamos un ejemplo:
Algoritmos y Estructuras de Datos
41


Problema: Leer 3 nmeros enteros e informar el valor del mnimo

programa principal funcion elmin ( p , q , r : enteros) : entera

leer ( a , b , c ) p<q y p<r
V F
menor elmin (a,b,c) (*)
q<r
escibir (El menor vale , menor) elmin p V F

elmin q elmin r
pudimos haber eliminado la variable menor
y tambin la asignacin (*) y en la escritura
poner escibir (El menor vale , elmin(a,b,c))

program funcio(input,output);
var a , b , c , menor : integer ;
function elmin( p , q , r : integer ) : integer ;
begin if p<q and p<r then elmin:= p
else if q<r then elmin:= q
else elmin:= r
end;
begin read ( a , b , c ); ac empieza a ejecutarse el programa, lo anterior es declaratorio
menor:= elmin( a , b , c );
write (El menor vale, menor)
end.

Los parmetros p, q, r que utilizamos en la definicin de la funcin se llaman parmetros
formales (o virtuales), ya que slo sirven para definir el tipo de proceso que sufrir cada uno.
Los parmetros a, b, c que utilizamos en la llamada a la funcin se llaman parmetros
actuales (o verdaderos), ya que es con esos valores con los que trabajar la funcin.

Tambin dijimos que los parmetros podan ser de cualquier tipo, y puede haber cualquier
cantidad de parmetros los cuales a su vez pueden ser de diferente tipo.
Veamos, por ejemplo una funcin que calcule el determinante de una matriz cuadrada de 3x3.
. . . . .
function sarrus( m : array [1..3,1..3] of real ) : real ;
var suma , resta : real ;
begin
suma :=m[1,1]*m[2,2]m[3,3]+m[1,2]*m[2,3]*m[3,1]+m[2,1]*m[3,2]*m[1,3];
resta:=m[3,1]*m[2,2]m[1,3]+m[2,1]*m[1,2]*m[3,3]+m[3,2]*m[2,3]*m[1,1];
sarrus:=suma-resta
end ;
. . . . .
Las variables definidas en la function se llaman variables locales (a la propia function) y slo son
reconocidas dentro de ella pero desconocidas fuera.


Vamos a hacer otro problema, donde construiremos la funcin para calcular por Sarrus un
determinante de 3x3 pero sus argumentos sern tres vectores y la usaremos para resolver un
sistema no homogneo de 3x3.
Y al sistema

Algoritmos y Estructuras de Datos
42

en vez de verlo as lo pensaremos as

a
11
. x
1
+ a
12
. x
2
+ a
13
. x
3
= b
1
p
1
.

x
1
+ q
1
. x
2
+ r
1
. x
3
= b
1
a
21
. x
1
+ a
22
. x
2
+ a
23
. x
3
= b
2
p
2
.

x
1
+ q
2
. x
2
+ r
2
. x
3
= b
2
a
31
. x
1
+ a
32
. x
2
+ a
33
. x
3
= b
3
p
3
.

x
1
+ q
3
. x
2
+ r
3
. x
3
= b
3

Problema: Leer por filas la matriz de los coeficientes de un sistema de 3x3, a coeficientes reales.
Leer luego el vector de los trminos independientes. Calcular la solucin e informarla
(supondremos que tiene solucin nica)
en la funcin pienso
program TresPorTres(input,output); el determinante as:
type v3 = array[1..3] of real; f
1
g
1
h
1

var p, q, r, b, x: v3; i: integer; detcoef: real; f
2
g
2
h
2
function sarrus2 (f, g, h:v3): real; f
3
g
3
h
3

var suma , resta: real;
begin suma := f(1)*g(2)*h(3) + f(2)*g(3)*h(1) + f(3)*g(1)*h(2);
resta:= f(3)*g(2)*h(1) + f(2)*g(1)*h(3) + f(1)*g(3)*h(2);
sarrus2 = suma resta
end;
begin ac empieza a ejecutarse el programa, lo anterior es declaratorio
for i:=1 to 3 do read (p[i], q[i], r[i]);
for i:=1 to 3 do read (b[i]);
detcoef:= sarrus2(p,q,r);
x[1]:= sarrus2(b,q,r) / detcoef;
x[2]:= sarrus2(p,b,r) / detcoef;
x[3]:= sarrus2(p,q,b) / detcoef;
write (Las races son );
for i:= 1 to 3 do write(x[i])
end.


Las funciones pueden ser recursivas, es decir que pueden invocarse a si mismas.
Un ejemplo clsico es la funcin factorial. ( podemos pensar n! = n
x
(n-1)! )
El siguiente ejemplo muestra por pantalla el factorial de enteros entre 1 y 10

program factori(input,output);
var i:integer; z:char;
function facto(n:integer):integer;
begin if n<=0 then facto:=1
else facto:=n*facto(n-1)
end;
begin for i:=1 to 10 do writeln(facto(i):10);
read(z)
end.


El resultado de la ejecucin de este programa es
1
2
6 que pas con los tres ltimos nmeros ?
24 el factorial crece muy rpidamente
120 el factorial de 8 dara 40.320 que excede
720 el valor permitido para los enteros
Algoritmos y Estructuras de Datos
43
5040 la capacidad rebals y dio un valor inesperado
-25216
-30336 la solucin hubiese sido poner
24330 function facto(n:integer):longint;


Antes de terminar con el tema reiteramos un concepto importante: Las funciones devuelven un
solo dato a travs de su nombre. (hay una aclaracin al final del captulo)
Esto para diferenciarlas del siguiente tema:


Procedimientos:

Los procedimientos tienen un funcionamiento parecido a las funciones, pero no devuelven nada a
travs de su nombre. Pueden devolver valores (ninguno, uno o varios) a travs de sus
parmetros. Por lo tanto habr parmetros de entrada, de salida, o incluso de entrada/salida al
procedimiento.

A los parmetros que slo sirven para entrar datos desde el programa (sera mas correcto decir
desde el mdulo invocante) al procedimiento (o sea los de entrada) los llamaremos parmetros
por valor, a los parmetros que sirven para devolver datos desde el procedimiento al programa (o
sea los de salida, o los de entrada/salida) los llamaremos parmetros por referencia.

Veamos su forma de trabajar:
Los parmetros por valor, son copiados dentro del procedimiento y el procedimiento trabaja sobre
esa copia, por lo tanto no se devuelve nada a travs de ellos.
Cuando los parmetros son por referencia, no son copiados al procedimiento, sino que el
procedimiento trabaja sobre el parmetro actual (es decir sobre las variables del programa)
pudiendo por lo tanto salir datos del procedimiento hacia fuera.

En este punto, debemos hacer una aclaracin. En muchos lenguajes, como por ejemplo Pascal, el
tipo de parmetro (por valor o por referencia) debe ser declarado en el propio procedimiento. Por
lo tanto todas las veces que sea invocado el procedimiento, cada parmetro trabajar de la misma
forma, siempre por valor o siempre por referencia.
El Fortran por ejemplo permite no definir en el procedimiento la forma de trabajo de cada
parmetro, sino que lo deja para el momento de la llamada. Es decir que dentro de un mismo
programa, en Fortran, para un procedimiento en particular podra ocurrir que haya parmetros que
en una llamada trabajen por valor y en otra llamada por referencia.

Los parmetros formales, es decir los que aparecen en la declaracin del subprograma, deben ser
nombres de variables (no pueden ser constantes ni expresiones), y estas variables pueden ser de
cualquier tipo (entero, real, arreglo, registro, ).
Los parmetros actuales, es decir, los que aparecen en la llamada al subprograma, pueden ser
constantes, variables o expresiones si la llamada es por valor. Si la llamada es por referencia, slo
pueden ser variables. En las funciones, los parmetros formales son todos por valor.
Debe haber correspondencia entre los parmetros actuales y los formales, tanto en cantidad
como en el orden y como en el tipo.



Problema: Leer los coeficientes a y b y resolver la ecuacin a.x + b = 0 ( a distinto de cero )

program unaprueba(input,output);
var a , b , x : real ;
Algoritmos y Estructuras de Datos
44
procedure ecua( p , q : real ; var r : real ) el parmetro r, al tener antepuesta la
begin r := -q / p palabra var, trabajar por referencia,
end ; los otros dos, al no tenerla, sern por valor
begin read ( a , b ); ac empieza a ejecutarse el programa, lo anterior es declaratorio
ecua ( a , b , x );
write (La raz es, x )
end.
Veamos ahora como se trabaja en la memoria
memoria



x programa
a

se copia a en p b

r apunta a x procedimiento
p se copia b en q
r

q






Cualquier funcin o procedimiento puede llamar a otra funcin y/o procedimiento, y as
sucesivamente, es decir que puede ocurrir una sucesin o cadena de llamadas entre funciones y
procedimientos.


los objetos son accesibles
M en el bloque en los bloques
------------ --------------
P M M , P , A , B , Q , R , S
P P , A , B
A A A , B
B B
B Q Q , R , S
R R
S S



Q

R


S






Algoritmos y Estructuras de Datos
45

Veamos otro ejemplo para indicar la diferencia entre parmetros por valor y por referencia.
En el programa principal, se inicializan dos variables enteras con el mismo valor 5, ambas se
corresponden como parmetros actuales, con parmetros formales que dentro del procedimiento
son incrementaos ambos en 3, la nica diferencia es que uno de los parmetros es por valor y el
otro por referencia.

program prueba( output ) ;
var a , b : integer ;
procedure cambia ( x : integer ; var y : integer);
begin x := x + 3 ;
y := y + 3 ;
writeln ( x , y)
end ;
begin a := 5 ;
b := 5 ;
writeln ( a , b );
cambia ( a , b ) ;
write ( a , b )
end .

Este programa producir la siguiente salida 5 5
8 8
5 8

No necesariamente los procedimientos deben tener parmetros, mas an, a veces pueden no
devolver nada al programa (o devolver a travs de variables globales). Veamos un ejemplo de
procedimiento sin parmetros.

Problema: Leer un vector entero de 20 elementos. Buscar el mnimo elemento (suponer que es
nico), su posicin, e informar ambos valores

program minimo1( input , output ) ;
var a: array[1..20] of integer ; i: integer;
procedure buscamin1;
var min , posmin: integer ; min y posmin son variables locales, slo se ven desde
begin min := a[1] ; posmin := 1; el procedimiento (se desconocen fuera del mismo)
for i:= 2 to 20 do if a[i] < min then begin min := a[i] ;
posmin := i
end ;
write(Minimo vale,min, en posicion,posmin)
end ;
begin for i:= 1 to 20 do read ( a[i] ) ;
buscamin1
end.

Observaciones: El procedimiento trabaj sobre la variable global a, tambin us la variable global
i. El procedimiento no necesit devolver lo calculado, ya que lo inform directamente por pantalla.
En este ejemplo el uso de procedimiento simplemente permiti modularizar la solucin.

Veamos otro ejemplo donde se har necesario el uso de parmetros.

Problema: Leer un vector de 20 elementos enteros, buscar el mnimo elemento, su posicin e
informarlos. Leer luego otro vector de 20 elementos enteros, buscar el mnimo elemento, su
Algoritmos y Estructuras de Datos
46

posicin e informarlos. Finalmente leer otro vector de 20 elementos enteros, buscar el mnimo
elemento, su posicin e informarlos. Por ltimo, informar el promedio de los tres mnimos.
program minimo2( input , output ) ;
var a: array[1..20] of integer ; min1, min2, min3, i: integer; p: real;
procedure buscamin2(var min: integer);
var posmin: integer ;
begin min := a[1] ; posmin := 1;
for i:= 2 to 20 do if a[i] < min then begin min := a[i] ;
posmin := i
end ;
write(Minimo vale,min, en posicion,posmin)
end ;
begin for i:= 1 to 20 do read ( a[i] ) ; buscamin2(min1);
for i:= 1 to 20 do read ( a[i] ) ; buscamin2(min2);
for i:= 1 to 20 do read ( a[i] ) ; buscamin2(min3);
p := (min1+min2+min3)/3;
write( y el promedio de los minimos vale ,p)
end.

Veamos otro problema, supongamos que en diferentes partes de un programa, quiero clasificar
tres arreglos, de diferente nombre y diferente cantidad de elementos.
Podemos hacer un procedimiento para clasificar un arreglo (por burbuja por ejemplo), pero los
parmetros formales y actuales deben corresponderse en tipo, es decir que si un parmetro
formal es un arreglo de 30 elementos enteros, el actual DEBE ser de 30 elementos enteros, no
puede ser, por ejemplo, ni de 29 ni de 31.
La solucin es hacer un procedimiento que tenga como parmetros el arreglo y tambin la
cantidad de elementos del arreglo, y a todos los arreglos darles el tamao del mayor. Veamos
Problema: Leer un vector a de 20 elementos enteros, clasificarlo en forma creciente e imprimirlo
clasificado. Leer luego un vector b de 28 elementos enteros, clasificarlo en forma creciente e
imprimirlo clasificado. Finalmente, leer un vector c de 15 elementos enteros, clasificarlo en forma
creciente e imprimirlo clasificado.
program clasificavarios( input , output ) ;
type v28 = array [ 1 .. 28 ] of integer ;
var a ,b ,c :v28 ; i :integer ;
procedure orden ( n :integer ; var x :v28) ;
var aux, j :integer ;
begin for i:= 1 to n-1 do
for j:= n-1 downto i do
if x[j] > x[j+1] then begin aux := x[j] ;
x[j] := x[j+1] ;
x[j+1] := aux
end
end ;
begin for i:= 1 to 20 do read(a[i]) ; orden ( 20 , a ) ;
for i:= 1 to 20 do writeln(a[i]) ;
for i:= 1 to 28 do read(b[i]) ; orden ( 28 , b ) ;
for i:= 1 to 28 do writeln(b[i]) ;
for i:= 1 to 15 do read(c[i]) ; orden ( 15 , c ) ;
for i:= 1 to 15 do writeln(c[i])
end.
Noten que en la declaracin del procedure hemos antepuesto la palabra var a x para que sea
parmetro por referencia y devuelva el arreglo clasificado al programa.

Algoritmos y Estructuras de Datos
47

Ahora vamos a hacer un comentario sobre la verdadera forma de trabajo de las funciones:

Si bien quienes escriben este apunte estiman que las funciones deben tener un funcionamiento similar al de
las de biblioteca, con la diferencia que son escritas por el programador, en realidad tambin pueden tener
parmetros por referencia, con lo que no slo devuelven un valor a travs de su nombre, sino tambin
valores a travs de sus parmetros si son declarados por referencia.
Como ejemplo, veamos el siguiente programa en el que a la variable k le asignamos el valor de la funcin (15
en el ejemplo) pero a j le asignamos antes del uso de la funcin el valor 9, pero cuando escribimos por
segunda vez j, ya est modificado y vale 10, en cambio i no se modifica.

program refenfun(input,output);
var i, j, k: integer;
function refe(x:integer; var y:integer): integer;
var t: integer;
begin t:= 0;
x:=x+1;
y:=y+1;
t:=x+y;
refe:=t
end;
begin i:=4; j:=9;
writeln(i:4,j:4);
k:=refe(i,j);
writeln(i:4,j:4,k:4);
readln
end.

La salida ser
4 9
4 10 15

Pero no tenemos que perder de vista que el objetivo es, entre otras cosas, aprender algoritmia y no Pascal a
fondo.
A lo largo de la profesin se encontrarn con lenguajes que si, debern conocerlos en profundidad, incluso
algunos que no han aparecido todava. En ese caso, debern investigar con mayor detalle.


Y para practicar un poco mas con funciones, otro comentario:
Las funciones pueden devolver datos de diferentes tipos, pero no de cualquier tipo. En general
pueden devolver datos de tipo integer (en todas sus variantes), real, char, boolean (en todas sus
variantes), string y pointer.
Pero tambin pueden devolver datos de tipo subrango o declarados por el programador.
Veamos el siguiente ejemplo donde le hacemos devolver un tipo declarado.

program fundecla(input, output);
type juan=(lun, martes, mierc, jueves);
var i: integer; pepe: juan;
function decla(z: integer):juan;
begin case z of
1: decla:= lun;
2: decla:= martes;
3: decla:= mierc;
4: decla:= jueves
end;
end;
Algoritmos y Estructuras de Datos
48
begin for i:=1 to 4 do begin pepe:= decla(i);
case pepe of
lun: write('Hola');
martes: write(' que');
mierc: write(' tal');
jueves: write(' amigos')
end
end;
readln
end.

La salida ser
Hola que tal amigos

Algoritmos y Estructuras de Datos
49
Registros:

Los arreglos permiten agrupar datos, pero todos del mismo tipo. Cuando tenemos necesidad de
agrupar datos de diferente tipo (no est prohibido que sean todos del mismo tipo) hacemos uso de
los record (registros). Por ejemplo supongamos que deseamos agrupar datos de los alumnos de
un curso (numero, nombre, notas enteras de 4 parciales, promedio), podemos hacer lo siguiente:


. . . . . .
type alu = record nro: integer;
nombre: string[6];
notas: array[1..4] of integer;
prome: real
end;
. . . . . .
var x , y , aux : alu ;
. . . . . .


numero, nombre, notas enteras de 4 parciales, promedio se denominan campos (field) del
registro y pueden ser de cualquier tipo, incluso record. Los campos pueden ser leidos
individualmente.

Supongamos en un momento del programa, el registro x contiene los siguientes datos


si en alguna parte del programa hago referencia a x, estoy refiriendo a todo el registro



275 e m i l i o 8 5 7 10 7.5



x . nro

x . nombre x . prome

x . notas x . notas [ 3 ]




Cualquiera de los datos ejemplificados puede utilizarse, por ejemplo, en una sentencia de
asignacin

aux := x





Problema: Leer los datos (numero, nombre, notas enteras de 4 parciales) de un cierto nmero de
alumnos (no se sabe cuantos, pero no son mas de 100) de un curso. Efectuar un listado
Algoritmos y Estructuras de Datos
50

clasificado por promedio decreciente. En caso de alumnos con igual promedio, deben aparecer en
orden alfabtico.

cant 0

leer nume

mientras nume > 0

cant cant + 1

curso
cant
. nro nume

leer curso
cant
. nombre

p 0

para i de 1 4

leer curso
cant
. notas
i


p p + curso
cant
. notas
i


curso
cant
. prome p / 4

leer nume

para i de 1 cant - 1

para j de cant 1 i

curso
j
. prome < curso
j + 1
. prome
V F

aux curso
j
curso
j
. prome =
curso
j + 1
. prome
curso
j
curso
j + 1
V F

curso
j + 1
aux curso
j
. nombre >
curso
j+1
.nombre
V F

aux curso
j


curso
j
curso
j + 1


curso
j + 1
aux

para i de 1 cant

escribir curso
i
. nro , curso
i
. nombre , curso
i
. prome

Algoritmos y Estructuras de Datos
51




program uncurso (input,output);
type alu = record nro:integer;
nombre:string[6];
notas:array[1..4]of integer;
prome:real
end;
var curso:array[1..100] of alu;aux:alu; i,j,cant,nume: integer; p: real;
begin cant:=0; read(nume);
while nume>0 do
begin cant:=cant+1; curso[cant].nro:=nume;
read(curso[cant].nombre); p:=0;
for i:=1 to 4 do begin read (curso[cant].notas[i]);
p:= p + curso[cant].notas[i]
end;
curso[cant].prome:= p/4; read(nume)
end;
for i:= 1 to cant-1 do
for j:= cant-1 downto i do
if curso[j].prome < curso[j+1].prome
then begin aux:= curso[j]; curso[j]:= curso[j+1];
curso[j+1]:= aux
end
else if curso[j].prome = curso[j+1].prome
then if curso[j].nombre > curso[j+1].nombre
then begin aux:= curso[j];
curso[j]:= curso[j+1];
curso[j+1]:= aux
end;
for i:= 1 to cant do
writeln(curso[i].nro, curso[i].nombre curso[i].prome)
end.

Aclaramos que sta no es la manera mas habitual de trabajar en casos como el anterior ya que:
- Los arreglos se trabajan en la memoria principal y luego de terminado el programa, sus
datos se pierden
- Los tamaos de los arreglos son fijos, por lo tanto debemos conocer el mismo de
antemano, o por lo menos la cantidad mxima de elementos a contener

Para casos similares lo mas prctico es trabajar con archivos.




A partir de la pgina siguiente entramos al tema Archivos. Se han incorporado muchos
temas. No significa que el alumno deba conocer en detalle, por ejemplo, altas, bajas,
modificaciones, etc. (temas que con seguridad vern con mas precisin y detalle mas
adelante en otras materias). El nico objeto de haberlos incluido es para que tengan una
buena cantidad de ejercicios de diferente caracter, lo que seguramente les permitir
comprender con mayor detalle el tema de tratamiento de archivos en Pascal.
Algoritmos y Estructuras de Datos
52
Archivos:

El archivo es una estructura de datos que permite conservarlos despus de la finalizacin del
programa ya que no se guardan en la memoria principal, sino en la auxiliar.
Hay varias formas de armar archivos: archivos de registros, archivos de arreglos, archivos de
caracteres, archivos de reales, archivos de enteros, archivos de matrices, etc.

Otra clasificacin de archivos es: secuenciales, directos, indexados. (dibujos para archivos de registros)

En los archivos secuenciales, para acceder a un registro, se debe pasar por los anteriores, no se
puede acceder directamente. Estos archivos pueden implementarse en cualquier tipo de soporte,
cintas, discos, etc.
xx para acceder a este registro

xxdebo pasar antes por todos los anteriores

.
registro registro registro registro registro registro registro
a .
archivo


En los archivos directos se pude acceder a cualquier registro directamente, sin necesidad de
pasar por los anteriores. Evidentemente, para conseguir esto, cada registro debe tener una clave
o un campo que le permita al programa, mediante algn clculo, ir directamente a la posicin de
memoria donde est almacenado el registro. No se pueden implementar en cintas.

x para acceder a este registro
xx voy directamente, no necesito pasar por los anteriores


.
registro registro registro registro registro registro registro
a .

No se describen los indexados ya que sern ampliamente tratados en otras asignaturas.

En este apunte de apoyo, veremos principalmente archivos orientando la explicacin a como se
los trata en Pascal.

Veamos algunas definiciones y sentencias Pascal.

En nuestros programas nos referiremos a los archivos mediante un nombre simblico, es decir
similar a como referenciamos una variable.
Supongamos que nuestro archivo es c : \ AyED \ Anio2011 \ comercio.dat y que ya existe,
Vamos a referirnos a l mediante un nombre simblico, por ejemplo unarchi, para asociarlos
tenemos la sentencia assign. En nuestro programa tenemos que tener algo as:

program unaprueba(input, output);
type producto=record nro: integer;
nombre: string[10];
precio: real
end; estamos suponiendo que comercio.dat
almacen = file of producto; es un archivo de registros
Algoritmos y Estructuras de Datos
53
var unarchi: almacen; ...
begin assign(unarchi,' c : \ AyED \ Anio2011 \ comercio.dat'); ...


Ahora bien, una variante para el assign sera que en vez de explicitar el nombre completo del
archivo utilicemos una variable de tipo string y que mediante una sentencia read o readln
introduzcamos el nombre del archivo, lo cual le da mas ductilidad al programa. Por ejemplo


program otraprueba(input, output);
type producto=record nro: integer;
nombre: string[10];
precio: real
end;
almacen = file of producto;
var unarchi: almacen; elarch: string[20]; ...
begin readln(elarch); assign(unarchi,elarch); ...


El archivo puede estar ya con datos cargados (por ejemplo por otro programa), puede estar vaco,
o puede no existir.

Pero Cmo hacemos para crear un archivo?. Hay muchas maneras. Veremos una que nos va a
permitir crear un archivo vaco. Desde la pantalla de Pascal (no desde el programa), en el men
de barras de la parte superior, hacemos click en file (o archivo), se descuelga un popup, click
en save (o guardar) y en la ventana que aparece al costado escribimos el nombre del archivo.

Ahora bien, en el programa, para poder comenzar a trabajar con el archivo (leer registros, grabar
registros), tenemos que abrirlo, esto lo podemos lograr con la sentencia reset. Esta sentencia
abre el archivo y queda posicionado para leer o grabar en el primer registro. Tendramos entonces

program unaprueba(input, output);
type producto=record nro: integer;
nombre: string[10];
precio: real
end;
almacen = file of producto;
var unarchi: almacen; ...
begin assign(unarchi,'c : \ AyE \ Anio2011 \ comercio.dat');
reset(unarchi); ...


si dentro del programa, con el archivo ya abierto, despus de haber trabajado en l, volvemos a
poner reset, quedaremos nuevamente preparados para leer o grabar en el primer registro.


Existe otra manera de crear (y abrir) archivos, con la sentencia rewrite, pero puede llegar a ser
peligrosa ya que borra los datos existentes si el archivo ya exista y tena datos cargados. De
todos modos, explicaremos su funcionamiento:
Si el archivo no existe, rewrite lo crea, pero si ya existe, lo abre y se pierden los datos que
contena.
Primero deben poner el assign y luego el rewrite o el reset.


Algoritmos y Estructuras de Datos
54
Al terminar de trabajar con el archivo, siempre debemos cerrarlo, lo que logramos con close
en el programa anterior deberamos poner la sentencia close(unarchi)


Existe una funcin que nos devuelve el tamao del archivo en cantidad de registros, es filesize.
Si para este archivo (supongamos que lo referenciamos como zarch),

.
registro registro registro registro registro registro registro
a .

tenemos en el programa filesize(zarch), nos devolver el entero 7. Podramos tener, por
ejemplo una sentencia n:= filesize(zarch) (estamos suponiendo que n es de tipo integer)

En Pascal los registros tienen asignados nmeros enteros consecutivos a partir de 0.

.
registro 0 registro 1 registro 2 registro 3 registro 4 registro 5 registro 6
a .
vvv sealador o puntero
(en este caso apuntando al registro 4)


Podemos pensar que los archivos tienen un sealador o puntero que siempre est apuntando
al prximo registro a ser procesado.

La funcin filepos devuelve el nmero del registro apuntado, para el dibujo anterior,
filepos(zarch) devolver el entero 4.

La instruccin seek posiciona el puntero en el registro a ser procesado. Por ejemplo
seek(zarch,5) har que el puntero apunte al registro 5.

En vez de poner un nmero entero, podemos poner una variable de tipo integer. Por ejemplo
seek(zarch,k) (donde suponemos que es k una variable entera que tiene un cierto valor).


Veamos ahora dos instrucciones que se usan para leer informacin de un archivo o grabar
informacin en un archivo. Son, respectivamente read y write.
.x(ejemplificamos para archivo de registros)

read(variableTipoArchivo,variableTipoRegistro) lee el registro apuntado y lo asigna
a la variable variableTipoRegistro, y pasa a apuntar al registro siguiente.

write(variTipoArchivo,variTipoRegistro) graba el registro contenido en la variable
variTipoRegistro en la posicin apuntada y pasa a apuntar al registro siguiente.



notemos que leemos o grabamos registros completos

Reiteramos: despus del read y/o del write el puntero pasa a apuntar al registro siguiente.


Algoritmos y Estructuras de Datos
55



El tema de lo que grabamos o leemos de archivos es sencillo si lo analizan con el siguiente
criterio:

Supongamos que en el programa tenemos var a:file of t ,

Si t es de tipo entero, tendr un archivo de enteros y cada vez que haga write(a,v), v tendr
que ser tipo entero y grabar en mi archivo un nuevo entero (y avanzar al entero siguiente).
Cada vez que haga read(a,v), v tendr que ser tipo entero y leer de mi archivo un entero (y
avanzar al entero siguiente).

Si t es de tipo real, tendr un archivo de reales y cada vez que haga write(a,v), v tendr que
ser tipo real y grabar en mi archivo un nuevo real (y avanzar al real siguiente). Cada vez que
haga read(a,v), v tendr que ser tipo real y leer de mi archivo un real (y avanzar al real
siguiente).

Si t es de tipo registro, tendr un archivo de registros y cada vez que haga write(a,v),
v tendr que ser tipo registro y grabar en mi archivo un nuevo registro (y avanzar al registro
siguiente). Cada vez que haga read(a,v), v tendr que ser tipo registro y leer de mi archivo un
registro (y avanzar al registro siguiente).

Si t es de tipo vector, tendr un archivo de vectores y cada vez que haga write(a,v),
v tendr que ser tipo vector y grabar en mi archivo un nuevo vector (y avanzar al vector
siguiente). Cada vez que haga read(a,v), v tendr que ser tipo vector y leer de mi archivo un
vector (y avanzar al vector siguiente).

Si t es de tipo matriz, tendr un archivo de matrices y cada vez que haga write(a,v),
v tendr que ser tipo matriz y grabar en mi archivo una nueva matriz (y avanzar a la matriz
siguiente). Cada vez que haga read(a,v), v tendr que ser tipo matriz y leer de mi archivo una
matriz (y avanzar a la matriz siguiente).


Finalmente veamos la funcin eof (end of file). Esta funcin devuelve true despus de haberse
procesado el ltimo registro del archivo (es decir si el puntero apunta al final del archivo), caso
contrario, devuelve false.


Los siguientes tres programas son nada mas que para resaltar que lo que se escribe en un
archivo perdura aunque el programa termine. Adems, para variar un poco, no vamos a trabajar
con archivo de registros, sino de reales.


Supongamos que en Pascal ejecutamos el siguiente programa:

program pantalla(input,output);
var x: real;
begin
write('Ingrese un real'); readln(x); write(x);
write('Ingrese un real'); readln(x); write(x);
write('Ingrese un real'); readln(x); write(x);
write('Ingrese un real'); readln(x); write(x);
Algoritmos y Estructuras de Datos
56
write('Ingrese un real'); readln(x); write(x)
end.

nos pedir cinco veces que ingresemos por teclado un real y lo grabar en la pantalla.

Supongamos que ingresamos los reales 1.75 -2.0 1.0 3.1 y -1.11


La pantalla se mostrar mas o menos as:

Ingrese un real 1.75
1.7500000000E+00
Ingrese un real -2.0
-2.0000000000E+00
Ingrese un real 0.0
1.0000000000E+00
Ingrese un real 3.1
3.1000000000E+00
Ingrese un real -1.11
-1.1100000000E+00


Hemos puesto en verde claro los carteles y en verde oscuro lo que ingresamos por teclado y
lo que est en negro representa lo que muestra el programa por pantalla.



Cuando el programa termina y comenzamos cualquier otro trabajo, la pantalla se borra y los datos
que haba en ella se pierden.

Supongamos que no queremos perder los datos leidos. Vamos a guardarlos en un archivo al que
llamaremos archifac.dat al que lo pondremos en una carpeta cualquiera, por ejemplo c:\com99.
Para hacer referencia al archivo en el programa lo llamaremos prueba.

Simplemente cambiamos las write esas

program archifac1(input,output);
var prueba: file of real; x: real;
begin assign(prueba, 'c:\com99\archifac.dat');
rewrite(prueba);
write('Ingrese un real'); readln(x); write(prueba,x);
write('Ingrese un real'); readln(x); write(prueba,x);
write('Ingrese un real'); readln(x); write(prueba,x);
write('Ingrese un real'); readln(x); write(prueba,x);
write('Ingrese un real'); readln(x); write(prueba,x); close(prueba)
end.

Ahora, (suponiendo que ingresamos los mismos cinco valores) el archivo c:\com99\ archifac.dat
qued con esos cinco valores ya mencionados grabados, los cuales se conservarn.


1.75 -2.0 1.0 3.1 -1.11


Algoritmos y Estructuras de Datos
57
Si por ejemplo queremos usar ese archivo en otro momento, podemos ver, por ejemplo, el
siguiente programa que lee uno a uno los valores guardados (los cinco ya mencionados), los
muestra por pantalla, los va sumando y finalmente muestra el valor de esa suma.

program archifac2(input,output);
var prueba: file of real; pum, tota: real; rta:char;
begin assign(pepe, 'c:\com99\archifac.dat');
reset(pepe); tota:= 0.0; notar que pusimos reset y no rewrite
while not eof(pepe) do begin read(pepe, pum);
writeln(Leo el valor , pum:10:3);
tota:= tota + pum
end;
close(pepe);
write(Los valores suman , tota:10:3, pulse una tecla . . .);
read(rta)
end.

y verificarn que fueron guardados y ledos correctamente.

A la variable con que leemos del archivo la hemos llamado voluntariamente pum para resaltar que
no es necesario usar los mismos nombres para leer que para escribir (basta con que se respete el
tipo). Tambin hemos referido al archivo con otro nombre simblico (pepe).

Pasemos a ver unos cuantos ejemplos


Algoritmos y Estructuras de Datos
58

Problema: Se supone que desde el men de barras de Pascal fue creado el archivo
c : \ archi04.dat y que est vaco. Leer de teclado los datos de un cierto nmero de alumnos
(nombre:string[6], nota:entero), no se sabe cuantos alumnos son, e ir guardndolos en dicho
archivo. A medida que se van leyendo los alumnos, ir asignndole nmeros enteros consecutivos
a partir de 1.
Listarlos e informar cuantos alumnos fueron grabados en el archivo.


program file01(input, output);
type alumno=record nro: integer;
nombre: string[6];
nota: integer
end;
curso=file of alumno;
var com22: curso; aux: alumno; canti: integer; brenom: string[6];
begin assign(com22, 'c:\archi04.dat'); reset(com22)(*);
canti:=0; readln(brenom);
while brenom<>'******' do begin canti:=canti+1;
aux.nro:=canti;
aux.nombre:=brenom;
readln(aux.nota);
write(com22,aux);
read(brenom)
end;
reset(com22);
writeln(Nro. Nombre Nota);
writeln(---- ------ ----);
while not eof(com22) do
begin read(com22, aux);
write(aux.nro:4, , aux.nombre, aux.nota:7)
end;
close(com22);
writeln('Fin de la grabacion, se grabaron ',canti,' alumnos')
end.
Si el archivo no hubiese existido, en vez de (*) hubiramos tenido que poner rewrite(com22)

Supongamos que nos piden que, ingresando un Nro. de alumno informemos Nombre y Nota

program file02(input, output);
type alumno=record nro: integer;
nombre: string[6];
nota: integer
end;
curso=file of alumno;
var com22: curso; aux: alumno; n, t: integer;
begin assign(com22,'c:\archi04.dat'); reset(com22); t:= filesize(com22);
write(Ingrese Nro. alumno a buscar sus datos); readln(n);
while n<1 or n>t do begin write(Incorrecto, ingrese de nuevo);
readln(n)
end;
seek(com22,n-1); read(com22,aux); write(aux.nombre, aux.nota);
close(com22)
end.
Algoritmos y Estructuras de Datos
59
No siempre hay un dato en el registro que acte como clave de manera que permita ubicar
directamente el registro con un seek.
Supongamos que queremos crear el archivo c:\com44.dat pero que los nmeros de alumno, si
bien son nicos para cada alumno, no tengan ningn orden.
Supongamos que sean enteros positivos. Un programa para crear el archivo, leyendo los datos de
los alumnos, listarlo e informar cuantos alumnos se grabaron sera:

program file03(input, output);
type alumno=record nro: integer;
nombre: string[6];
nota: integer
end;
curso=file of alumno;
var comis: curso; aux: alumno; n: integer;
begin assign(comis, 'c:\com44.dat'); rewrite(comis);
read(n);
while n>0 do begin aux.nro:= n; para no complicar el algoritmo
read(aux.nombre); estamos suponiendo que no se
readln(aux.nota); ingresan dos alumnos con un
write(comis,aux); mismo nmero
read(n)
end;
reset(comis);
writeln(Nro. Nombre Nota);
writeln(---- ------ ----);
while not eof(comis) do
begin read(comis, aux);
write(aux.nro:4, , aux.nombre, aux.nota:7)
end;
close(comis);
writeln('Fin grabacion, se grabaron ',filesize(comis),' alumnos')
end.

Supongamos que nos piden que, ingresando un Nro. de alumno informemos Nombre y Nota.
Ahora no podemos ubicar el alumno con un seek ya que no hay ninguna relacin que vincule al
nmero del alumno con el nmero del registro. No tenemos mas remedio que recorrer el archivo
desde el principio hasta encontrar (o no) al alumno. Y si no lo encontramos, informarlo.

program file04(input, output);
type alumno=record nro: integer;
nombre: string[6];
nota: integer
end;
curso=file of alumno;
var comis: curso; aux: alumno; n: integer;
begin assign(comis, 'c:\com44.dat'); reset(comis);
read(n); read(comis, aux);
while n<>aux.nro and not eof(comis) do read(comis, aux);
if n=aux.nro then write(aux.nro:4, , aux.nombre, aux.nota:7)
else write(Alumno no encontrado);
close(comis)
end.

Algoritmos y Estructuras de Datos
60
Mas de una vez tendremos que trabajar con algn archivo que no sabemos si existe o no, pero si
existiera, no queremos perder los datos que contiene. No podemos usar rewrite.
Si usamos reset, en el momento de la ejecucin, el Sistema Operativo me informar de un error
de entrada/salida si no existiera. Para evitar esto, debo desactivar esta posibilidad a travs de la
instruccin {I-}. De esta manera podr seguir con el programa. Despus de una instruccin de
E/S, el Sist. Operat. devuelve un parmetro IORESULT que indica el tipo de error que encontr, si
vale cero es que no hubo error, si hubo error, entre otros valores, si devuelve 2, significa que el
archivo no fue encontrado. Es peligroso seguir con la verificacin desactivada, debo poner
enseguida {I+}.
Supongamos que se da esta situacin (de no saber si existe o no) con un archivo c:\opera.dat.
Mi programa debera comenzar mas o menos as:

program file00(input, output);
type alumno=record nro: integer;
nombre: string[6];
nota: integer
end;
curso=file of alumno;
var comis: curso; . . . .
begin assign(comis, 'c:\opera.dat'); {I-}; reset(comis);
if ioresult=2 then rewrite(comis); {I+}; . . . .

Sigamos practicando con archivos

Problema: Se supone que el archivo c : \ ejem.dat tiene una cierta cantidad (no se sabe
cuantos) de registros cargados. Se supone adems que el archivo c : \ alrreves.dat fue creado
desde el men de barras de Pascal y que est vaco. Se pide:
1) Listar el archivo ejem.dat
2) Grabar en alrreves.dat los registros de ejem.dat pero en el orden inverso
3) Listar alrreves.dat



program davuelta(input,output);
type libro=record nroint,codi,stock:integer;
titulo,autor:string[20];
precio:real
end;
negocio=file of libro;
var libros, dadovue : negocio ; aux:libro ; rta:char ;
n , i , k : integer ; (*) si en vez de tener alrreves.dat ya
begin assign(libros,'c:\ejem.dat'); creado, quisiramos crearlo en este
assign(dadovue,'c:\alrreves.dat'); programa, deberamos cambiar
reset(libros); reset(dadovue)(*); reset(dadovue) por rewrite(dadovue)
writeln('Nro Codigo Titulo Stock');
writeln('--- ------ -------------------- -----');
while not eof(libros) do
begin read(libros,aux) ;
writeln(aux.nroint:3,aux.codi:8,' ',aux.titulo,aux.stock:5)
end;
writeln('Fin del primer listado');
n:=filesize(libros);
for i:=1 to n do
begin k:= n-i;
Algoritmos y Estructuras de Datos
61
seek(libros,k);
read(libros,aux);
write(dadovue,aux);
end;
reset(dadovue);
writeln('Nro Codigo Titulo Stock');
writeln('--- ------ -------------------- -----');
while not eof(dadovue) do
begin read(dadovue,aux) ;
writeln(aux.nroint:3,aux.codi:8,' ',aux.titulo,aux.stock:5)
end;
writeln('Fin del segundo listado');
close(libros); close(dadovue);
writeln('Fin del programa, ingrese cualquier letra');
readln(rta)
end.

Varias veces ponemos al final del programa la instruccin readln(rta) nada mas que para que
la pantalla desaparezca recin despus de pulsar una tecla (para poder verificar los resultados).
A veces, en vez de leer un char haremos leer un entero. Tambin podemos poner readln.

Problema: Se supone que desde el men de barras de Pascal fue creado el archivo
c : \ libreria.dat y que est vaco. Leer de teclado los datos de una cierta cantidad de libros
(cdigo, ttulo, autor, precio, cantidad en stock) . A medida que se van leyendo los libros, ir
agregndolos al archivo asignndole nmeros enteros consecutivos a partir de 1. Luego de
cargados listar todos los libros.
Se desea luego realizar la venta de cierta cantidad de ejemplares de un libro, para lo cual deber
verificarse que haya suficiente cantidad en stock. El programa deber indicar si se puede o no
efectuar la venta, informar el precio y actualizar el stock.
Finalmente se repetir el listado.

program libreria(input,output);
type libro=record nroint,codi,stock:integer;
titulo,autor:string[20];
precio:real
end;
negocio=file of libro;
var
libros:negocio;aux:libro;unprecio:real;n,uncodi,unnro,unacanti:integer;
begin assign(libros , 'c:\libreria.dat');
reset(libros); n:=0;
write('Ingrese codigo(cero termina):');readln(uncodi);
while uncodi>0 do
begin n:=n+1 ; aux.nroint:=n ; aux.codi:=uncodi;
write('Ingrese titulo:');readln(aux.titulo);
write('Ingrese autor :');readln(aux.autor);
write('Ingrese precio:');readln(aux.precio);
write('Ingrese stock :');readln(aux.stock);
write(libros,aux);
write('Ingrese codigo (cero termina):');readln(uncodi)
end;
reset(libros);
writeln('Nro Codigo Titulo Stock');
writeln('--- ------ -------------------- -----');
Algoritmos y Estructuras de Datos
62
while not eof(libros) do
begin read(libros,aux) ;
writeln(aux.nroint:3,aux.codi:8,' ',aux.titulo,aux.stock:5)
end;
write('Ingrese nro. interno del libro a vender (entre 1 y ',n:3,'):');
readln(unnro); unnro:=unnro-1; (por la modalidad que elegimos para asignar el cdigo
write('Ingrese cantidad de ejemplares a vender:'); el libro de cdigo unnro ocupar
readln(unacanti); el registro unnro 1)
seek(libros,unnro) ; read(libros,aux); (me posiciono en el registro y lo leo)(pero, OJO, porque
if aux.stock>=unacanti then despues de leer ya qued apuntando al registro siguiente)
begin unprecio:=unacanti*aux.precio;
aux.stock:=aux.stock-unacanti;
write('Venta aceptada,importe:',unprecio:10:2);
writeln(' quedan en stock:',aux.stock:3);
seek(libros,unnro);write(libros,aux) (el seek es para volver a ubicarme
end en el registro, ya que el read me haba sacado)
else writeln('Venta rechazada por falta de stock');
reset(libros);
writeln('Nro Codigo Titulo Stock');
writeln('--- ------ -------------------- -----');
while not eof(libros) do
begin read(libros,aux) ;
writeln(aux.nroint:3,aux.codi:8,' ',aux.titulo,aux.stock:5)
end;
close(libros);
writeln('Fin')
end.


Trabajando con archivos, permanentemente estaremos haciendo Altas, Bajas y Modificaciones
(ABM).

Lo que va a ocurrir tambin muchas veces es que no sea tan fcil acceder directamente a un
registro a travs de una clave como en los casos anteriores.

Veamos un poco mas detalladamente en que consisten las tareas antes mencionadas,
ejemplificando para archivos de registros.

Altas: Consiste en agregar un nuevo registro al final del archivo (si se desea agregar varios, se
pone todo dentro de un while). Si, como en varios ejemplos anteriores un dato clave era asignado
por el programa, prcticamente sin verificar nada, agregamos el registro y el dato clave del nuevo
registro es asignado por el programa.
Muchas veces esto no es as, los registros en general tienen un campo identificatorio que suele
ser nico y que es propuesto por el usuario pero que no permite ubicar el registro. En este caso el
programa de altas debe verificar que no exista ya un registro con ese campo identificador, en cuyo
caso se informa y se rechaza el alta.

Bajas: Consiste en eliminar un registro del archivo (si se desea eliminar varios, se pone todo
dentro de un while). La eliminacin puede ser fsica o lgica, como se explicar mas adelante.
Ac, lo que debemos hacer es buscar el registro dentro del archivo (generalmente a travs de su
campo identificatorio), Si no se encuentra hay que avisar; si se encuentra, antes de eliminarlo, hay
que mostrar los datos caractersticos del registro, pedir confirmacin, y recin ah, eliminatlo.

Algoritmos y Estructuras de Datos
63
Modificaciones: Consiste en modificar algunos campos de un registro (si se desea modificar
varios registros, se pone todo dentro de un while). Tambin ac hay que ubicar el registro dentro
del archivo, cambiar los campos, y volver a grabarlo. Si no se encontr, hay que avisar.



Algunos comentarios sobre BAJAS en un archivo:

Cuando se intenta dar de baja a un registro de un archivo, hay dos maneras de hacerlo:

Baja fsica: consiste en hacer desaparecer el registro, corriendo todos los que estn a su
derecha un registro a la izquierda, con lo cual el registro borrado desaparece y el archivo
quedar con un tamao un registro menor al que tena. Los datos del registro dado de baja se
perdieron.

Baja lgica: consiste en incorporar a los registros un campo (booleano en los ejemplos, tambin
podra ser char, integer, etc.) que indique si el registro est dado de baja o no.
En el ejemplo, al campo en cuestin lo hemos llamado debaja.


Supongamos que queremos dar de baja al registro con nroint = 3 (el registro 2)

EOF
Baja lgica
antes.de la baja
0 false 1 false 2 false 3 false 4 false 5 false 6 false
a .reg 0 reg 1 reg 2 reg 3 reg 4 reg 5 reg 6.
despus.de la baja
0 false 1 false 2 true 3 false 4 false 5 false 6 false
a .reg 0 reg 1 reg 2 reg 3 reg 4 reg 5 reg 6

En rojo se idican los valores del nmero de registro
y en azul el valor de debaja (el campo que usamos para indicar si est dado de baja o no)
3 true sombreado indica que el registro tiene baja lgica

EOF
Baja fsica (no es necesario utilizar el campo debaja)
.

a .reg 0 reg 1 reg 2 reg 3 reg 4 reg 5 reg 6.

kjkkl EOF

a .reg 0 reg 1 reg 2 reg 3 reg 4 reg 5

Este tipo de baja tiene varios inconvenientes:
- Se perdieron los datos del registro dado de baja mientras que con la baja lgica, mediante
un simple mdulo muy similar al de modificaciones, se puede recuperar.
- Si hubiera un campo clave para ubicarlo directamente, ste deja de servir, por lo que
habra que redefinir los campos clave y listarlos (imaginar archivos con miles de registros) y
an as correramos el riesgo de cometer errores.



Algoritmos y Estructuras de Datos
64


A continuacin vamos a ver un programa que permita hacer alta, bajas modificaciones y listados.
Valen las siguientes aclaraciones:
- Los registros tienen un campo que permite ubicarlos directamente (nroint)
- Se pueden hacer cualquiera de las tareas enunciadas mediante un men de opciones
- El mdulo de altas permite hacer varias altas
- El mdulo de bajas permite hacer varias bajas
- El mdulo de modificaciones permite hacer modificaciones a un solo registro
- El mdulo de listados slo permite hacer un listado

Problema: Para el archivo de la librera de uno de los ejemplos anteriores (es decir que el archivo
ya existe), a cuyos registros se agreg un campo booleano (debaja), confeccionar un programa
Pascal que pueda efectuar Altas, Bajas, Modificaciones (slo modificaremos precio y stock) y
Listados. Las Bajas sern lgicas, es decir no eliminarn el registro, sino que colocarn en true el
campo debaja. Las Altas debern poner el mismo campo en false. En los listados, no se listan los
libros que tengan dicho campo en true.

program completo(input,output);
type libro=record nroint,codi,stock:integer;
titulo,autor:string[20];
debaja:boolean;
precio:real
end;
negocio=file of libro;
var libros:negocio ; aux:libro ; rta:char ;
n , uncodi , uninte , op : integer ;
begin assign(libros,'c:\ejem.dat');reset(libros);
writeln('Menu');writeln('----');writeln('1-Altas');writeln('2-Bajas');
writeln('3-Modificaciones');writeln('4-Listados');writeln('5-Salir');
write('Elija su opcion:');readln(op);
while op<5 do
begin
case op of
1: begin writeln('Modulo de altas');writeln('---------------');
n:=filesize(libros); seek(libros,n); me voy al final del archivo para agregarlos
write('Ingrese codigo(cero termina):');readln(uncodi);
while uncodi>0 do
begin aux.nroint:=n+1 ; aux.codi:=uncodi;
write('Ingrese titulo:') ; readln(aux.titulo);
write('Ingrese autor :') ; readln(aux.autor);
write('Ingrese precio:') ; readln(aux.precio);
write('Ingrese stock :') ; readln(aux.stock);
aux.debaja:=false ; write(libros,aux); n:=n+1;
write('Ingrese codigo (cero termina):');readln(uncodi)
end ;
writeln('Fin del modulo de altas')
end;
2: begin writeln('Modulo de bajas');writeln('---------------');
write('Ingrese Nro. interno(cero termina):');readln(uninte);
while uninte>0 do
begin uninte:=uninte-1 ; seek(libros,uninte) ;
read(libros,aux) ;
writeln('Codigo:',aux.codi) ;
Algoritmos y Estructuras de Datos
65
writeln('Titulo:',aux.titulo) ;
write('Lo da de baja ? (S/N):');readln(rta);
if rta='S' then begin aux.debaja:=true ;
seek(libros,uninte);
write(libros,aux)
end;
write('Ingrese Nro. interno(cero termina):');
readln(uninte);
end ;
writeln('Fin del modulo de bajas')
end;
3: begin writeln('Modulo de modificaciones');
writeln('------------------------');
write('Ingrese nro. interno del libro a modificar:');
readln(uninte); uninte:= uninte - 1;
seek(libros,uninte);read(libros,aux);
writeln('El libro es');writeln(aux.nroint,' ',aux.titulo);
write('Ingrese nuevo precio:');readln(aux.precio);
write('y nueva cantidad en stock:');readln(aux.stock);
seek(libros,uninte);write(libros,aux);
writeln('Fin de la modificacion')
end;
4: begin writeln('Modulo de listados');
writeln('------------------');
reset(libros);
writeln('Nro Codigo Titulo Stock');
writeln('--- ------ -------------------- -----');
while not eof(libros) do
begin read(libros,aux) ;
if not aux.debaja then
writeln(aux.nroint,aux.codi,' ',aux.titulo,aux.stock)
end;
writeln('Fin del listado')
end;
end;
writeln('Menu');writeln('----');
writeln('1-Altas');writeln('2-Bajas');
writeln('3-Modificaciones');writeln('4-Listados');
writeln('5-Salir');
write('Elija su opcion:');readln(op)
end;
close(libros);
writeln('Fin del programa, ingrese cualquier letra');readln(rta)
end.



En el ejemplo anterior, algunas cosas se hacan mas sencillas por el hecho que era fcil ubicar
directamente cualquier registro mediante un simple clculo (en los ejemplos, restndole 1 al
nmero del artculo).

Muchas veces esto no es posible. Veamos un ejemplo sencillo.

Algoritmos y Estructuras de Datos
66
Supongamos que tenemos un negocio que tiene un archivo c:\ ferrete.dat donde guardan los
datos de los artculos que venden.
Los datos de los artculos son:
- nmero del artculo (entero positivo) (no puede haber nmeros de artculos repetidos)
- nombre del artculo (cadena de 6 caracteres)
- precio (real)
Al registro le vamos a agregar un campo booleano para indicar si est dado de baja o no.

A fin de simplificar la comprensin vamos a hacer tres programas separados (uno de altas, otro de
bajas y otro de modificaciones).
Para simplificar mas la cosa, vamos a hacer una sola alta, una sola baja y una sola modificacin.
Si quieren hacer varias, se hace lo de siempre, se pone todo dentro de un mientras.
Los registros estn grabados en cualquier orden y los nmeros de artculo no tienen por que ser
correlativos.
Vamos a suponer que el archivo ya tiene registros cargados, es decir que puede tener el siguiente
aspecto


x 146 Pinza 75.80 f 33 Tenaza 70.30 t 44 Clavos 8.00 f .... 31 Pincel 15.95 f

con f estamos indicando false es decir que el artculo NO est dado de baja y con t indicamos
true, o sea que ese artculo fue dado de baja

Vamos a escribir el programa de altas.
Vamos a pedir antes que nada el nmero del artculo al que quiero dar de alta para verificar que
no exista en el archivo, ya que si existe, no podemos permitir un alta con el mismo nmero.
Tambin vamos a adoptar el criterio que aunque exista, pero est dado de baja, tampoco lo
vamos a permitir (podramos haber adoptado un criterio opuesto)
Para ver si ya existe el nmero de artculo no podemos hacer otra cosa que recorrer desde el
principio todo el archivo

program altas (input,output);
type arti=record nro:integer;
descri:string[6];
precio:real;
debaja:boolean
end;
var a:file of arti; r:arti; n:integer; esta:boolean;
begin assign(a, 'c:\ ferrete.dat'); reset(a);
write('Ingrese numero de articulo a dar de alta'); readln(n);
esta:=false;
while not eof(a) and not esta do begin read(a,r);
if r.nro=n then esta:=true
end;
if esta then writeln('Numero ya existe, alta rechazada')
else begin r.nro:=n; r.debaja:=false;
write('Ingrese nombre del articulo');
readln(r.descri); notemos que si el nmero no
write('y su precio'); exista, estamos en el eof, y
readln(r.precio); el write(a,r) va a grabar el registro
write(a,r) al final del archivo, el cual pasa a
end; tener un registro mas.
close(a)
end.
Algoritmos y Estructuras de Datos
67
Vamos a escribir el programa de bajas.
Vamos a pedir el nmero del artculo a dar de baja y recorremos el archivo desde el principio. Si
encontramos el artculo, ponemos el campo debaja en false.

program bajas (input,output);
type arti=record nro:integer;
descri:string[6];
precio:real;
debaja:boolean
end;
var a:file of arti; r:arti; n:integer;
begin assign(a, 'c:\ ferrete.dat'); reset(a);
write('Ingrese numero de articulo a dar de baja'); readln(n);
read(a,r); para cambiar un poco no usamos
while not eof(a) and r.nro<>n do read(a,r); la variable booleana esta
if r.nro<>n then writeln('No existe el articulo')
else begin r.debaja:=true;
seek(a,filepos(a)-1); vuelvo un registro atrs ya que
write(a,r); haba avanzado un registro
write('El articulo ',r.descri,' fue eliminado')
end;
close(a)
end.

Por ltimo, vamos a escribir el programa de modificaciones.
Vamos a permitir modificar el campo descri y el campo precio. No es recomendable cambiar el
campo que funciona como clave nica de identificacin, en nuestro caso nro (aunque tambin
podramos hacerlo). Tampoco permitimos modificar el campo debaja, ya que para ello tenemos el
mdulo descrito anteriormente.
El algoritmo es bastante similar al anterior (bajas).

program modifica (input,output);
type arti=record nro:integer;
descri:string[6];
precio:real;
debaja:boolean
end;
var a:file of arti; r:arti; n:integer;
begin assign(a, 'c:\ ferrete.dat'); reset(a);
write('Ingrese numero de articulo a modificar'); readln(n);
repeat read(a,r) until r.nro=n or eof(a); ahora lo recorr con repeat-until
if r.nro<>n then writeln('No existe el articulo')
else begin write('Articulo ',r.descri);
writeln(' ingrese nuevos datos');
write('Descripcion:');readln(r.descri);
write('Precio :');readln(r.precio);
seek(a,filepos(a)-1);
write(a,r)
end;
close(a)
end.


Un mdulo para listar el archivo sera prcticamente igual al de la librera.
Algoritmos y Estructuras de Datos
68



A continuacin vamos a ver un ejemplo para confirmar que con cada read y write, el puntero
avanza una posicin.
La idea es grabar 4 reales (10.0 20.0 30.0 40.0) y luego poner en su lugar la mitad de cada
uno, tapando al valor original.

Primero vamos a cometer una omisin, leeremos y grabaremos olvidndonos que cada vez que
lee pasa al siguiente, veremos entonces que:
lee el 10.0, lo divide por 2 y graba tapando al 20.0 (dejando el 10.0 igual) pero ya apunta al 30.0
lee el 30.0, lo divide por 2 y graba tapando al 40.0 dejando el 30.0 igual

Despus vamos a grabar 5 en vez de 4 (10.0 20.0 30.0 40.0 50.0) y con el mismo olvido
lee el 10.0, lo divide por 2 y graba tapando al 20.0 (dejando el 10.0 igual) pero ya apunta al 30.0
lee el 30.0, lo divide por 2 y graba tapando al 40.0 (dejando el 30.0 igual) pero ya apunta al 50.0
lee el 50.0 y pasa al EOF, por lo tanto el write siguiente agrega un real mas (25.0). Quedaron 6
reales en el archivo.

Finalmente pondremos la solucin correcta

program verskip(input,output);
var pruskip: file of real ; i, fsz, fps:integer; x:real; rta:char ;
begin assign(pruskip,'c:\diviprog\algori~1\ejempl~1\verskip.dat');
rewrite(pruskip); writeln('Voy a grabar 4 reales');
for i:=1 to 4 do begin x:= 10.0 * i; grabo los reales
write(pruskip,x) 10.0 20.0 30.0 40.0
end;
fsz:= filesize(pruskip);
writeln('Se grabaron', fsz:3, ' reales a saber');
reset(pruskip);
while not eof(pruskip) do begin read(pruskip,x);
writeln(x:8:2) los listo
end;
reset(pruskip);
writeln('Ahora leo, divido por 2 y grabo');
while not eof(pruskip) do begin read(pruskip,x); leo, pero paso al sig.
x:=x/2; grabo en el siguiente
write(pruskip,x) la mitad del ledo
end;
fsz:= filesize(pruskip);
writeln('Sigue habiendo', fsz:3, ' reales a saber');
reset(pruskip);
while not eof(pruskip) do begin read(pruskip,x);
writeln(x:8:2) los listo
end;
rewrite(pruskip); hago rewrite para borrar lo que se haba grabado
writeln('Ahora borro todo y grabo 5 en vez de 4');
for i:=1 to 5 do begin x:= 10.0 * i;
write(pruskip,x) todo lo mismo pero
end; grabo 5 reales
fsz:= filesize(pruskip);
writeln('Se grabaron', fsz:3, ' reales a saber');
reset(pruskip);
Algoritmos y Estructuras de Datos
69
while not eof(pruskip) do begin read(pruskip,x);
writeln(x:8:2) los listo
end;
reset(pruskip);
writeln('Ahora leo, divido por 2 y grabo');
while not eof(pruskip) do begin read(pruskip,x); al leer el ultimo real
x:=x/2; paso al EOF y grabo
write(pruskip,x) agregando un registro
end; mas
fsz:= filesize(pruskip);
writeln('Pero ahora quedaron', fsz:3, ' reales a saber');
reset(pruskip);
while not eof(pruskip) do begin read(pruskip,x);
writeln(x:8:2) los listo
end;
writeln('Si quiero que cada real quede dividido por 2, hago');
rewrite(pruskip); writeln('Voy a grabar 4 reales');
for i:=1 to 4 do begin x:= 10.0 * i; genero de nuevo el archivo original con
write(pruskip,x) 10.0 20.0 30.0 40.0
end;
fsz:= filesize(pruskip);
writeln('Se grabaron', fsz:3, ' reales a saber');
reset(pruskip);
while not eof(pruskip) do begin read(pruskip,x);
writeln(x:8:2) los listo
end;
reset(pruskip);
writeln('Ahora leo, divido por 2 y grabo');
while not eof(pruskip) do begin
fps:= filepos(pruskip); memorizo donde leo
read(pruskip,x);
x:=x/2;
seek(pruskip,fps); y vuelvo para grabar
write(pruskip,x) en el mismo lugar
end;
writeln('Y lo que quedo grabado es');
reset(pruskip);
while not eof(pruskip) do begin read(pruskip,x);
writeln(x:8:2)
end;
write('Pulse...'); read(rta) para que no se borre la pantalla hasta pulsar
end.

La salida de este programa es

Voy a grabar 4 reales
Se grabaron 4 reales a saber
10.00
20.00
30.00
40.00
Ahora leo, divido por 2 y grabo
Sigue habiendo 4 reales a saber
10.00
Algoritmos y Estructuras de Datos
70
5.00
30.00
15.00
Ahora borro todo y grabo 5 en vez de 4
Se grabaron 5 reales a saber
10.00
20.00
30.00
40.00
50.00
Ahora leo, divido por 2 y grabo
Pero ahora quedaron 6 reales a saber
10.00
5.00
30.00
15.00
50.00
25.00

Si quiero que cada real quede dividido por 2, hago
Voy a grabar 4 reales
Se grabaron 4 reales a saber
10.00
20.00
30.00
40.00
Ahora leo, divido por 2 y grabo
Y lo que quedo grabado es
5.00
10.00
15.00
20.00
Pulse...


Vamos a hacer otro ejemplo:

Un grupo de amigos decide organizar un Quini4 (similar al Quini6 pero las apuestas son de cuatro
nmeros) no puede haber nmeros repetidos en las apuestas. Hacer un programa Pascal para:
- Leer todas las boletas (nmero de boleta, nombre del apostador, los cuatro nmeros de su
apuesta) e ir grabando cada boleta en c: \ apueq4.dat
- Informar cuantas boletas se grabaron
- Leer luego los cuatro nmeros sorteados
- Leer cada boleta de c: \ apueq4.dat y grabar cada boleta que tenga cuatro aciertos (es
decir, cada boleta ganadora) en c: \ gananq4.dat
- Para calcular la cantidad de aciertos usar una funcin aciertos
- Informar la cantidad de boletas ganadoras y listarlas


program quini4(input,output);
type v4=array[1..4] of integer;
apuesta=record nro:integer;
nom:string[6];
apu:v4
Algoritmos y Estructuras de Datos
71
end;
archivos=file of apuesta;
var apuestas, ganaron: archivos; i, j, n, z: integer; rta: char;
a: apuesta; lagana: v4;
function aciertos(p, q: v4): integer;
begin z:= 0;
for i:=1 to 4 do
for j:=1 to 4 do
if p[i]=q[j] then z:= z + 1;
aciertos:=z
end;
begin assign(apuestas,'c:\apueq4.dat'); rewrite(apuestas);
assign(ganaron,'c:\gananq4.dat'); rewrite(ganaron);
write('Ingrese Nro. de apuesta (cero termina) ');
readln(n);
while n>0 do
begin a.nro:= n; write('Ingrese nombre '); readln(a.nom);
write('Y ahora los 4 nros. de la apuesta ');
for i:=1 to 4 do read(a.apu[i]);
write(apuestas, a); writeln;
write('Ingrese Nro. de apuesta (cero termina) ');
readln(n)
end;
writeln('Se grabaron', filesize(apuestas):3, ' apuestas');
write('Ingrese los 4 numeros sorteados ');
for i:=1 to 4 do read(lagana[i]); writeln;
reset(apuestas);
while not eof(apuestas) do
begin read(apuestas,a);
if aciertos(a.apu , lagana)=4 then write(ganaron,a)
end;
if filesize(ganaron)=0
then writeln('No hubo ganadores')
else begin writeln(filesize(ganaron):3,' ganadores');
reset(ganaron);
while not eof(ganaron) do
begin read(ganaron,a);
write(a.nro:4,' ', a.nom);
for i:=1 to 4 do write(a.apu[i]:3);
writeln
end
end;
write('Pulse...'); read(rta);
close(apuestas); close(ganaron)
end.


Tambin habamos dicho que podamos tener archivos de vectores. Veamos un ejemplo

Armar un archivo que contenga 5 vectores. Los vectores sern de 4 enteros y sus valores
debern ser 1 2 3 4 / 11 12 13 14 / 21 22 23 24 / 31 32 33 34 / 41 42 43 44
Leer luego cada vector, listarlo e indicar la suma de sus elementos.
Finalmente indicar la suma total

Algoritmos y Estructuras de Datos
72
program ArDeVec(input,output);
type v4=array[1..4] of integer;
var z:file of v4; i, j, k, sp, st:integer; v:v4;
begin assign(z,'c:\ArDV');rewrite(z);
for i:= 1 to 5 do
begin for j:= 1 to 4 do v[j]:= 10*(i-1) + j;
write(z,v)
end;
reset(z); writeln;
st:=0;
for i:= 1 to 5 do
begin read(z,v);
write('Vector',i:2);
sp:=0;
for j:= 1 to 4 do begin write(v[j]:4);
sp:=sp+v[j]
end;
writeln(' que suma',sp:4);
st:=st+sp
end;
writeln('y la suma total es',st:4,' ingrese un entero...');
read(k);
close(z)
end.



Finalmente hagamos un ejemplo con un archivo de matrices

Leer por filas tres matrices enteras de 2 filas y 4 columnas con el siguiente criterio:
leer cada matriz y grabarla en el archivo c:\ArDeMat.dat, el archivo quedar entonces con tres
registros, donde cada registro contendr una matriz se 2x4.
volver al principio del archivo, leer una a una las matrices, mostrarlas por filas en la pantalla,
indicando adems, que matriz es la que leen (el orden en que fue ingresada), el nmero del
registro y la suma de cada fila

program ArDeMat(input,output);
type m24=array[1..2,1..4] of integer;
var i, j, k, q, tf: integer; z: file of m24; m:m24;
begin assign(z,'c:\aldo\ArDeMat.dat'); rewrite(z);
for k:=1 to 3 do begin writeln('Ingrese una matriz por filas');
for i:=1 to 2 do for j:=1 to 4 do read(m[i,j]);
write(z,m)
end;
reset(z); k:=0;
while not eof(z) do begin q:= filepos(z); k:= k+1; read(z,m);
writeln('Matriz',k:2,' grabada en reg.',q:2);
for i:=1 to 2 do begin tf:=0;
for j:=1 to 4 do
begin tf:=tf+m[i,j];
write(m[i,j]:6)
end;
writeln(' fila',i:2,' suma',tf:6)
end
Algoritmos y Estructuras de Datos
73
end;
write('Ingrese un numero:');read(k)
end.


Existe una cierta similitud entre la ubicacin lgica de los elementos de un archivo y los elementos
de un arreglo unidimensional (ya sean dichos elementos registros, o enteros, o reales, etc.)

Por lo tanto muchas veces se pueden usar en archivos tcnicas que fueron explicadas en
arreglos.

Supongamos que tenemos

v: array [1..N] of t donde N es una constante entera y t es cualquier tipo
a: file of t pensemos tambin que a tiene N elementos
supongamos que aux es una variable de tipo t

pensemos que queremos asignar el si queremos asignar el elemento i-simo
elemento de posicin i del arreglo a del archivo a la variable aux, y siempre
la variable aux, en el programa de- recordando que el primer elemento del
beramos escribir archivo es el de posicin 0, haramos
aux := v[i] seek(a,i-1)
read(a,aux)

Algo que debemos tener en cuenta es que el arreglo puede tener ndice no-entero, y an siendo
entero, puede no empezar en 1 (aunque esto es raro). En este caso habra que modificar el
algoritmo para tratar el archivo.


Ordenamiento de Archivos:

Vamos a usar el mtodo de ordenamiento por seleccin del mnimo.
Vamos a ejemplificar sobre un archivo de enteros, pero la metodologa es la misma si se quiere
ordenar por un determinado campo en un archivo de registros.

program OrdeArch(input,output);
var a:file of integer;i,j,min,aux,posmin,k,n:integer;
begin assign(a,'c:\ArPaOrd.dat');reset(a);n:=filesize(a);
for i:=0 to n-2 do begin seek(a,i);
read(a,k);
aux:=k;
min:=k;
posmin:=filepos(a)-1;
for j:=i+1 to n-1 do
begin seek(a,j);
read(a,k);
if k<min then begin min:=k;
posmin:=filepos(a)-1
end
end;
seek(a,i);
write(a,min);
seek(a,posmin);
Algoritmos y Estructuras de Datos
74
write(a,aux)
end;
reset(a);writeln('El archivo quedo asi');
while not eof(a) do begin read(a,k);
write(k:4)
end;
writeln;write('Ingrese un entero');read(j)
end.

Si desean probar el programa anterior o hacerle modificaciones, tengan presente que el programa
anterior modifica el archivo ya que lo ordena sobre si mismo. Entonces sera bueno generar el
archivo nuevamente cada vez que vayan a probar el programa. Para ello, tienen el programa
siguiente que arma un archivo con 11 enteros a saber

35 22 -6 -9 0 12 17 -60 33 1 -19

program ArPaOrd(input,output);
var v:array[1..11] of integer; a:file of integer;i,j,k:integer;
begin assign(a,'c:\ArPaOrd.dat');rewrite(a);
v[1]:= 35; v[2]:= 22; v[3]:= -6; v[4]:= -9; v[5]:= 0; v[6]:= 12;
v[7]:= 17; v[8]:=-60; v[9]:= 33; v[10]:= 1; v[11]:=-19;
for i:=1 to 11 do write(a,v[i]);reset(a);
writeln('El archivo quedo asi');
while not eof(a) do begin read(a,k);
write(k:4)
end;
writeln;write('Ingrese un entero');read(j)
end.


Ahora hagamos un ordenamiento de un archivo pero por burbuja.
Podra ser el mismo enunciado que el anterior, y si quieren generar el archivo pueden usar
pero cambiando el nombre ArPaOrd.dat por burbarch.dat

program burbarch(input, output);
var b: file of integer; ant, post, i, j, n: integer;
begin assign(b, 'c:\burbarch.dat');
reset(b);
writeln('Archivo antes de ordenar');
writeln('------------------------');
while not eof(b) do begin read(b, ant);
write(ant:5)
end; writeln;
n:= filesize(b);
for i:=0 to n-2 do
for j:=n-2 downto i do
begin seek(b,j);
read(b, ant);
read(b, post);
if ant>post then begin seek(b,j);
write(b,post);
write(b,ant)
end;
end;
reset(b);
writeln('Archivo despues de ordenar');
Algoritmos y Estructuras de Datos
75
writeln('--------------------------');
while not eof(b) do begin read(b, ant);
write(ant:5)
end; writeln;
close(b); readln
end.



Bsqueda en Archivos:

En la gran mayora de los ejemplos anteriores hemos realizado bsquedas secuenciales.
Veamos entonces como haramos una bsqueda dicotmica.
Recordemos que la bsqueda dicotmica funciona si donde queremos buscar est ordenado.
Podramos buscar en el archivo anterior, despus de haberlo ordenado. Es decir en
-60 -19 -9 -6 0 1 12 17 22 33 35
Vamos a ejemplificar sobre un archivo de enteros, pero la metodologa es la misma si se quiere
buscar un determinado campo en un archivo de registros. La bsqueda secuencial ya la hicimos varias
veces (en algunos ejemplos de altas, bajas y modificaciones)

program BusEnArc(input,output);
var a:file of integer; me,imin,imax,imedio,k,i:integer;
begin assign(a,'c:\ArPaBus.dat');reset(a);
writeln('El archivo esta asi');
while not eof(a) do begin read(a,k);
write(k:4)
end;reset(a);
writeln;write('Ingrese el entero a buscar');readln(k);
imin:=0;imax:=filesize(a)-1;imedio:=(imin+imax) div 2;
seek(a,imedio);read(a,me);
while (k<>me) and (imin<=imax) do
begin if k<me then imax:=imedio-1
else imin:=imedio+1;
imedio:=(imin+imax) div 2;
seek(a,imedio);read(a,me)
end;
if k=me then writeln('Esta en el registro',imedio:4)
else writeln('No esta');
write('Ingrese un entero ');readln(k)
end.


Intercalacin de Archivos:

Vamos a ejemplificar sobre un ejercicio del examen del 07 / 12 / 2010.

Examen Algoritmos y Estructuras de Datos

Una empresa tiene dos sucursales. De cada sucursal dispone de un archivo C: \ SUCU1.DAT y
C: \ SUCU2.DAT. Cada archivo contiene los datos de los artculos de esa sucursal, a saber:
- Nmero del artculo (entero)
- Nombre del artculo (20 caracteres)
- Precio unitario (real)
- Cantidad en stock (entero)
Algoritmos y Estructuras de Datos
76

Artculos iguales tienen el mismo nmero, nombre y precio en ambas sucursales, pero pueden
tener distinto stock. Puede haber artculos que figuren en el archivo de una sucursal y en el de
otra no, y artculos que figuren en los archivos de ambas.

Los nmeros de artculos no son consecutivos.

Ambos archivos estn ordenados por nmero de artculo creciente.

Se pide diagrama de Chapin y programa Pascal para:

1) Generar un archivo C: \ EMPRESA.DAT que contenga los datos de todos los artculos, tambin
ordenado por nmero de artculo creciente, un solo registro por artculo y stock totalizado.
Es decir que podramos tener una situacin como la siguiente:
SUCU1.DAT SUCU2.DAT EMPRESA.DAT
35 GOMAS 3.75 45 35 GOMAS 3.75 12 35 GOMAS 3.75 57
56 LAPICES 8.40 83 44 BROCHES 4.40 60 44 BROCHES 4.40 60
80 RESMAS 22.80 14 75 CLIPS 3.65 30 56 LAPICES 8.40 83
120 TINTA 9.90 8 80 RESMAS 22.80 33 75 CLIPS 3.65 30
. . . . . . . . . . . . . . . . . . . . 80 RESMAS 22.80 47
. . . . . . . . . . . . . . . . . . . . 120 TINTA 9.90 8
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2) Ingresar por teclado un entero que ser el porcentaje de descuento que se efectuar a los
artculos cuyo stock sea superior a 50 unidades.

3) Modificar el archivo C: \ EMPRESA.DAT segn el criterio enunciado en el punto anterior.

4) Listar C: \ EMPRESA.DAT completo.

NOTA: No se conoce la cantidad de registros de SUC1.DAT y SUC2.DAT pero no estn vacos



program ExaDic10(input,output);
type artic=record nro:integer;
nombre:string[10];
precio:real;
stock:integer
end;
archi=file of artic;
var a,b,c:archi; rc,ra,rb:artic; n,m,i,j, t:integer;
begin assign(a,'c:\SUCU1.DAT');assign(b,'c:\SUCU2.DAT');
assign(c,'c:\EMPRESA.DAT');rewrite(c);reset(a);reset(b);
i:=1; j:=1; n:=filesize(a); m:=filesize(b); read(a,ra); read(b,rb);
while (i<=n) and (j<=m) do
begin
if ra.nro<rb.nro then begin
write(c,ra);
if not eof(a) then read(a,ra);
i:=i+1
end;
if rb.nro<ra.nro then begin
write(c,rb);
if not eof(b) then read(b,rb);
j:=j+1
end;
if ra.nro=rb.nro then begin rc:=rb;
Algoritmos y Estructuras de Datos
77
rc.stock:=ra.stock+rc.stock;
if not eof(a) then read(a,ra);
if not eof(b) then read(b,rb);
write(c,rc);
i:=i+1;
j:=j+1
end
end;
if i>n then for t:=j to m do begin write(c,rb);
if not eof(b) then read(b,rb)
end
else for t:=i to n do begin write(c,ra);
if not eof(a) then read(a,ra)
end;
reset(c); write('Ingrese porcentaje a rebajar:'); read(n);
while not eof(c) do begin read(c,rc);
if rc.stock>50 then begin rc.precio:=rc.precio*(1-n/100.0);
seek(c,filepos(c)-1);
write(c,rc)
end
end;
writeln('El archivo EMPRESA.DAT quedo asi'); reset(c);
while not eof(c) do begin read(c,rc);
writeln(rc.nro:4,rc.nombre,rc.precio:6:2,rc.stock:6)
end;
close(a);close(b);close(c)
end.
Se ha tratado de asimilar al algoritmo de intercalacin usado para arreglos. El alumno puede practicar cambiando los (i<=n), etc.
por not eof(a), etc y tambin cambiando algunos while o for por repeat.

A continuacin vamos a resolver un ejemplo similar (el examen del 07/12/11), pero en vez de resolverlo como el anterior haciendo una
analoga con intercalacin de archivos, lo resolveremos trabajando directamente con eof(), etc. Trabajando de esta manera, hay que
tomar algunas precauciones extra, ya que podra omitirse garabar el o los ltimos registros de los archivos, etc.


Algoritmos y Estructuras de Datos Examen 07 de Diciembre de 2.011 .-

Una Facultad tiene registrado (entre otros archivos de datos) las Notas de los exmenes de sus
alumnos. Por cada alumno que rindi un examen se guard:
Legajo del alumno: entero / Cdigo de la asignatura: string[6] / Nota: real
(tambin tiene otros archivos: alumnos, materias, etc. pero no son necesarios para este problema)
Los datos antes mencionados estn guardados en dos archivos:
Los exmenes del Ciclo Bsico en c:\ basico.dat
Los exmenes del Ciclo Profesional en c:\ profesio.dat
Un mismo alumno puede tener varios registros en ambos archivos. Ambos archivos estn
ordenados por Legajo del alumno, en forma no-decreciente (por lo tanto todos los registros de un
mismo alumno estarn en posiciones adyacentes).
Existe adems un archivo, ya creado, pero vaco c:\juntos.dat.

Se pide Chapin y programa Pascal para:
1- que c:\juntos.dat. contenga los datos de c:\ basico.dat y c:\ profesio.dat tambin
ordenado por Legajo creciente. (si, por ejemplo un alumno tiene 4 registros en
c:\basico.dat y 2 registros en c:\ profesio.dat, deber tener 6 en c:\juntos.dat). Listarlo
completo (todos los registros).
2- Hacer un listado del archivo c:\juntos.dat que contenga Legajo y Promedio de cada
alumno, una sola lnea por alumno. Por promedio se entiende la suma de las Notas del
alumno dividida por la cantidad de Materias rendidas por ese alumno.



Algoritmos y Estructuras de Datos
78
Por ejemplo, suponiendo que los archivos contienen:

basica.dat profesio.dat
17 B111 6.0 1er. reg. 17 P043 6.0
17 B112 7.5 ... 2do. reg. ... 22 P100 9.0
45 B111 6.5 ... 3er. reg. ... 22 P103 8.5
64 B064 8.5 ... 4to. reg. ... 64 P053 8.5
74 B222 4.0 5to. reg. 64 P031 6.0

La salida debera ser algo as


Listado de juntos.dat
---------------------
17 B111 6.0
17 B112 6.0 no deben preocuparse por el orden en que
17 P043 7.5 aparecen los registros para legajos iguales
22 P100 9.0 lo importante es que sea por legajo no-decreciente
22 P103 8.5
45 B111 6.5
64 B064 8.5
64 P053 6.0
64 P031 8.5
74 B222 4.0
Listado de promedios
--------------------
17 6.50
22 8.75
45 6.50
64 7.67
74 4.00



program ExaDic11(input,output);
type alu=record lega:integer;
materia:string[6];
nota: real
end;
facu=file of alu;
var a,b,c:facu; rc,ra,rb,aux:alu; legant,sulega,n,m,i,j,t:integer;
prome, suma: real; puseldea, puseldeb: boolean;
begin assign(a,'c:\basica.dat');assign(b,'c:\profesio');
assign(c,'c:\juntos.dat');rewrite(c);rewrite(a);rewrite(b);
aux.lega:=17;
aux.materia:='B111';
aux.nota:=6.0;
write(a,aux);
aux.lega:=17;
aux.materia:='B112';
aux.nota:=7.5;
write(a,aux);
aux.lega:=45;
aux.materia:='B111';
aux.nota:=6.5;
write(a,aux);
aux.lega:=64;
aux.materia:='B064';
aux.nota:=8.5;
Algoritmos y Estructuras de Datos
79
write(a,aux);
aux.lega:=74;
aux.materia:='B064';
aux.nota:=8.5;
write(a,aux);
aux.lega:=74;
aux.materia:='B068'; hemos puesto las sentencias sombreadas
aux.nota:=8.5; para generar nuevamente los archivos
write(a,aux); cada vez que se corre el programa, por
aux.lega:=88; si desean probar diferentes soluciones.
aux.materia:='B033'; tambin habra que cambiar rewrite por reset
aux.nota:=8.5;
write(a,aux);
aux.lega:=17;
aux.materia:='P043'; hemos agregado mas registros que los que
aux.nota:=6.0; figuran en el ejemplo del enunciado
write(b,aux);
aux.lega:=22;
aux.materia:='P100';
aux.nota:=9.0;
write(b,aux);
aux.lega:=22;
aux.materia:='P103';
aux.nota:=8.5;
write(b,aux);
aux.lega:=64;
aux.materia:='P053';
aux.nota:=8.5;
write(b,aux);
aux.lega:=64;
aux.materia:='P031';
aux.nota:=6.0;
write(b,aux);
reset(a); reset(b);
writeln('Listado del archivo basica.dat');
while not eof(a) do begin read(a,rc);
writeln(rc.lega,' ',rc.materia,' ',rc.nota:6:2)
end;
reset(c); writeln('Listado del archivo profesio.dat');
while not eof(b) do begin read(b,rc);
writeln(rc.lega,' ',rc.materia,' ',rc.nota:6:2)
end;
write('Pulse...'); readln;
reset(a); reset(b); read(a,ra); read(b,rb);
puseldea:=false; puseldeb:=false;
while not ((eof(a) and puseldea) or (eof(b) and puseldeb)) do
if ra.lega<=rb.lega then begin
sulega:=ra.lega;
write(c,ra);
puseldea:=true;
puseldeb:=false;
read(a,ra);
if eof(a) then
if ra.lega=sulega then write(c,ra)
end
else begin
sulega:=rb.lega;
write(c,rb);
puseldeb:=true;
puseldea:=false;
read(b,rb);
if eof(b) then
if rb.lega=sulega then write(c,rb)
end;
if eof(a) and puseldea then write(c,rb);
Algoritmos y Estructuras de Datos
80
if eof(b) and puseldeb then write(c,ra);
if eof(a) and puseldea then begin
while not eof(b) do begin
read(b,rb);
write(c,rb)
end
end
else begin
while not eof(a) do begin
read(a,ra);
write(c,ra)
end
end;
reset(c); writeln('Listado del archivo juntos.dat');
while not eof(c) do begin read(c,rc);
writeln(rc.lega,' ', rc.materia, rc.nota:6:2)
end;
reset(c); write('Pulse...'); readln;
read(c,rc); legant:= rc.lega; suma:= rc.nota; n:= 1;
while not eof(c) do begin read(c,rc);
if rc.lega<>legant then begin
prome:= suma/n;
n:= 1;
writeln(legant,prome:6:2);
suma:= rc.nota;
legant:= rc.lega
end
else
begin n:= n+1;
suma:= suma+rc.nota
end
end;
prome:= suma/n; writeln(legant, prome:6:2);
close(a);close(b);close(c);write('Pulse...'); readln
end.


Los archivos tambin pueden ser parmetros de funciones. Supongamos que tenemos dos
archivos del mismo tipo, curso1.dat y curso2.dat, y que en ambos deseamos calcular el
promedio de las notas de los alumnos, es decir la suma de las notas de curso1,dat dividido por la
cantidad de alumnos, y la suma de las notas de curso2.dat dividido por la cantidad de alumnos.
Vamos a hacer una nica funcin que calcule ese promedio para un archivo parmetro formal x, y
despus usamos como parmetros actuales los archivos mencionados.


program ArParFun(input, output);
type alu=record nom: string[4];
nota: integer
end;
archi= file of alu;
var aux: alu; a, b:archi; m: real;
function prome(var x: archi):real;
var w:alu; t:real;
begin reset(x); t:= 0;
while not eof(x) do begin read(x, w);
t:= t + w.nota
end;
prome:= t / filesize(x)
end;
begin assign(a,'c:\aldo\curso1.dat');
Algoritmos y Estructuras de Datos
81
assign(b,'c:\aldo\curso2.dat');
m:= prome(a); writeln('Curso1 tiene promedio', m:6:2);
m:= prome(b); writeln('Curso2 tiene promedio', m:6:2);
close(a); close(b); readln
end.

Notarn que hemos puesto var delante del parmetro formal x de la funcin, esto lo exige Pascal,
y es lgico, ya que los archivos son en general de gran tamao y no sera prctico (o sera
imposible) trabajarlos como parmetros por valor, es decir haciendo una copia de ellos en
memoria.



Para terminar, veamos un ejercicio mas sobre archivos

El objeto del siguiente ejemplo es simplemente que tengan mas ejercicios sobre archivos y
presentar una forma de interactuar con el sistema operativo desde un programa Pascal.

Cmo podemos hacer para dar una baja fsica?

Vamos a ejemplificar como dar de baja (eliminar, en caso de baja fsica) a un registro.
Es decir queremos que el registro a dar de baja desaparezca del archivo y que por lo tanto el
archivo quede un registro mas corto.

Vamos a programar el siguiente mtodo.


Supongamos que nuestro archivo se llama gente.dat y queremos eliminar un registro.
Creamos un archivo vaco (o hacemos rewrite), auxi.dat y copiamos en l uno a uno los registros
de gente.dat excepto el que queremos dar de baja.

Entonces va a quedar como pretendemos que quede nuestro archivo al dar una baja fsica


gente.dat

a eliminar




auxi.dat





Pero ahora tenemos un problema, nuestro archivo se llama auxi.dat, pero debera llamarse
gente.dat.
Borramos entonces nuestro gente.dat y luego a auxi.dat lo renombramos como gente.dat.

Esto lo podramos conseguir saliendo del Pascal y luego, desde Windows hacemos el borrado y el
renombrado que mencionamos antes.
Algoritmos y Estructuras de Datos
82
Sin embargo es mas seguro hacerlo desde el propio programa Pascal. Esta interaccin con los
sistemas operativos, se puede hacer desde cualquier lenguaje, en particular desde Pascal,
tenemos dos instrucciones, erase y rename, de muy fcil comprensin y que se incluyen
directamente en el programa siguiente.

En el programa, se tratar de dar de baja a un registro, al que identificaremos por el campo nro, el
cual se ingresar por teclado.
En realidad, el archivo gente.dat, debera existir, por lo que usamos reset(a).

Sin embargo en el programa hemos puesto las sentencias sombreadas para generarlo cada vez
que se corra el programa por si desean hacerle algunas mejoras, como por ejemplo:
- informar los datos del registro a borrar para pedir confirmacin de borrado (en el ejemplo se
informa que fue borrado)
- avisar si no se encontr
- etc


program bajafisi(input, output);
type gistro= record nro: integer;
nombre: string[4]
end;
chivo= file of gistro;
var abajar, p: integer; a, b, z: chivo; c: gistro;
begin assign(a,'c:\gente.dat');
assign(b,'c:\auxi.dat');
rewrite(a); rewrite(b);
c.nro:=111; c.nombre:='AAAA'; write(a,c);
c.nro:=222; c.nombre:='BBBB'; write(a,c);
c.nro:=333; c.nombre:='CCCC'; write(a,c);
c.nro:=444; c.nombre:='DDDD'; write(a,c);
c.nro:=555; c.nombre:='EEEE'; write(a,c);
c.nro:=666; c.nombre:='FFFF'; write(a,c);
reset(a);
writeln('El archivo contiene los siguientes registros');
while not eof(a) do begin read(a,c);
writeln(c.nro,' ',c.nombre)
end;
write('Indique el nro. de la persona a dar de baja :');
readln(abajar); reset(a);
while not eof(a) do begin read(a,c);
if c.nro=abajar then
writeln('Se da de baja a ', c.nombre)
else write(b,c)
end;
close(a); close(b);
erase(a); rename(b,'c:\gente.dat');
assign(z,'c:\gente.dat'); reset(z); writeln('Y ahora quedo asi');
while not eof(z) do begin read(z,c);
writeln(c.nro,' ',c.nombre)
end;
write('Ingrese un entero '); read(p); close(z)
end.

También podría gustarte