ARREGLOS EN PASCAL

Anuncio
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
ARREGLOS EN PASCAL.
Un arreglo en cualquier lenguaje de programación es una sucesión consecutiva de bytes en memoria. Los arreglos pueden representar:
Matrices (de 2 ó más dimensiones).
Vectores (de una sola dimensión).
La cantidad de bytes que ocupa un arreglo depende del tipo de dato que almacene
cada domicilio. Así un arreglo de 4 domicilios de tipo char ocupará 4 bytes, mientras
que un arreglo de 4 domicilios de tipo double ocupará 32 bytes. Este es un dato muy a
tener en cuenta cuando se dimensiona un arreglo a fin de no sobrecargar demasiado
la memoria.
La forma clásica de una matriz de m x n que nosotros representamos como:
m [filas]
n [columnas]
en una computadora no existe: allí los arreglos son siempre lineales.
La simulación a una matriz bidimensional se obtiene como (por ejemplo para una matriz M de 3 x 10):
1
10 11
Fila 1
20
Fila 2
30
Fila 3
La posición correspondiente para el elemento [2,4] vendría dada por la expresión:
Posición de M[2,4] = PosInicio + [(Fila – 1) x DIM2] + (Col-1)
Posición de M[2,4] = PosInicio + (2 – 1) x 10 + 3
Posición de M[2,4] = 13
Por supuesto, hemos asumido que cada elemento del arreglo contiene un dato de tipo
char o byte que solo ocupa 1 byte de memoria.
En caso de que cada domicilio contuviera un dato de mayor longitud, por ejemplo de
tipo Word, haríamos la siguiente modificación:
Posición de M[2,4] = PosInicio + [(Fila – 1) x DIM2 + (Col - 1)] x Sizeof(Tipo)
Es posible obtener una expresión para 3 dimensiones, pero normalmente trabajaremos
solo hasta 2.
Clase Teórica Nro 9
Pág 1/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
Declaración formal de un arreglo en Pascal.
var Mat : array[DIM1,DIM2]of <Tipo>;
En el cual DIM se especifica como un subrango de tipo ordinal que tiene un límite
inferior y un límite superior:
var
Mat : array[1..4,1..5]of integer;
Vect : array[1..100]of boolean;
Letras: array[1..27]of char;
etc.
En realidad lo conveniente es crear un “alias” para los arreglos, mediante una declarativa type:
const DIM1 = 4;
DIM2 = 5;
type TMat = array[1..DIM1,1..DIM2]of integer;
TVect = array[1..100]of boolean;
etc,
Luego en el bloque var ponemos:
var
Mat : TMat;
V1 : TVect;
etc.
El bloque type en realidad permite construir nuevos tipos de datos pero basados en los
que ya se hallan predefinidos en el lenguaje.
El límite inferior y superior de cada dimensión no tiene por qué arrancar siempre en 1
ni siquiera ser de tipo numérico. Las siguientes declarativas son perfectamente posibles:
type TMat = array[‘A’..’Z’]of char;
TVect = array[-10..-5]of double;
En el primer caso la variable de control de lazo deberá ser de tipo char y moverse entre estos dos límites:
var c : char;
for c:=’A’ to ‘Z’ do .....
Cómo se accesa un domicilio de un arreglo.
Los elementos de un arreglo pueden accesarse para leer o para escribir su contenido.
La forma de hacerlo es:
M[Fila,Col]:=.......
Vect[i]
:=.....
Clase Teórica Nro 9
Pág 2/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
ó bien: if(Mat[i,j]=....) then .....
Para asignar por completo un arreglo:
for i:=1 to DIM1 do
for j:=1 to DIM2 do
M[i,j]:=20+random(81);
Para mostrarlo en pantalla:
for i:=1 to DIM1 do begin
for j:=1 to DIM2 do write(M[i,j]:4);
writeln;
end;
Nótese que hemos utilizado la sentencia write( ) con formato para imprimir cada fila
completa sobre el mismo renglón y encolumnando con 4 espacios. El writeln sólo, se
emplea para bajar un renglón.
Un caso particular de arreglos: las cadenas.
Hasta ahora hemos estudiado un tipo individual de datos: los char o caracteres, que
representan cualquier elemento de la tabla ASCII (American Standard Code Information Interchange) o Código Standard Americano para el Intercambio de Información.
En esta tabla se hallan todos los caracteres alfabéticos, numéricos, de puntuación, caracteres especiales y caracteres de control. A nosotros sólo nos interesa los alfabéticos y numéricos. A cada caracter le es asignado un valor numérico único, por ejemplo:
A
B
C
....
a
b
c
...
65
66
67
0
1
2
48
49
50
97
98
99
{
}
[
123
125
91
Así, al pulsar un caracter cualquiera del teclado, el mismo genera automáticamente
alguno de estos códigos. Cuando muchos caracteres conforman palabras y texto,
Pascal provee un tipo especial de dato que permite manejarlos de forma muy cómoda
y sencilla: los datos de tipo string. Este tipo especial de dato se trata de un arreglo de
char, aunque en su sintaxis no aparezca la declarativa array[...]of char.
Su declarativa es la siguiente:
var
Texto : string;
Frase : string[80];
La primera (string), es la declarativa por defecto. Pascal asigna 255 espacios para almacenar caracteres. Si lo que vamos a manejar son cadenas pequeñas, podemos
acotar la cantidad de domicilios colocando entre corchetes el espacio requerido.
Clase Teórica Nro 9
Pág 3/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
El domicilio 0 (cero) tiene un uso muy particular: Pascal almacena allí (en forma de
equivalente char) la cantidad de caracteres que han ingresado a la cadena. De esta
forma:
Frase:=’Programación en Turbo Pascal’;
que contiene 28 caracteres, se almacena como:
0
Pr og r a m a c i ó n
en Turbo Pascal
Equivalente char de la longitud de la cadena
Cómo determinar la longitud de una cadena.
Pascal provee una función específica:
length( var string);
Que retorna un entero equivalente a la cantidad de caracteres de la cadena.
De esta manera:
Longitud:=length(Frase)
quedaría cargado con la magnitud 28.
Cuándo emplear arreglos en un problema.
Imaginemos que disponemos de una frase en la cual deseamos detectar la cantidad
de vocales a, e, i, etc., presentes en la misma.
type
var
TVoc = array[1..5]of integer;
Voc : TVoc;
Frase : string;
i
: integer;
begin
clrscr; highvideo;
Frase:=’Esta es una frase breve de prueba’;
for i:=1 to 5 do Voc[i]:=0;
for i:=1 to lenght(Frase) do
case Frase[i] of
‘a’,’A’ : Voc[1]:=Voc[1]+1;
‘e’,’E’ : Voc[2]:=Voc[2]+1;
‘i’,’I’ : Voc[3]:=Voc[3]+1;
‘o’,’O’ : Voc[4]:=Voc[4]+1;
‘u’,’U’ : Voc[5]:=Voc[5]+1;
end;
Clase Teórica Nro 9
Pág 4/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
for i:=1 to 5 do writeln(‘Vocal ‘,chr(64+i),’=’,Voc[i]);
readkey;
end.
Aquí aparecen un par de cositas nuevas: una extensión de la instrucción case y una
instrucción nueva: chr( ).
La estructura case permite varias posibilidades. En una clase anterior la mostrábamos
con un listado de constantes aisladas:
case VarOrdinal of
caso 1 : begin instrucciones 1; end;
case 2 : begin instrucciones 2 ; end;
case 3 : begin instrucciones 3; end;
..........
case n : begin instrucciones n; end;
end;
También admite la siguiente sintaxis:
case VarOrdinal of
Valor1 .. Valor2 : begin instrucciones 1; end;
Valor3 .. Valor4 : begin instrucciones 2; end;
etc.
end;
en la cual cada opción se trata de un subrango, como las categorías en los deportes:
case Edad of
5 .. 7 : writeln(‘categoría infantil’);
7 .. 10 : writeln(‘ categoría superjuvenil’);
10..13 : writeln(‘ ...................................’);
etc.
end;
Otra sintaxis admitida es una especie de enumeración:
case VarOrdinal of
valor1,valor2,... : begin instrucciones 1; end;
valor5,valor6,... : begin instrucciones 2; end;
etc.
end;
Obviamente utilizaremos esta notación cuando los valores de cada opción NO SEAN
CONSECUTIVOS, como en el caso de las vocales.
Volviendo a nuestro problema con los arreglos de char, no hubo ninguna dificultad para referirnos a cada caracter almacenado en el arreglo, con la consabida notación:
Frase[ i ]
Clase Teórica Nro 9
Pág 5/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
IMPORTANTE:
En un arreglo (matriz o vector) perteneciente a un determinado tipo, el contenido de
cada domicilio goza de las mismas propiedades que un dato aislado perteneciente al
mismo tipo. Por ejemplo:
var
n : integer;
V : array[1..10]of integer;
V[1], V[2], etc., gozan de las mismas propiedades que n, pues se trata de enteros:
DIV
división entera.
MOD resto de una división entera.
pred predecesor.
succ sucesor.
Otro ejemplo en el cual conviene utilizar arreglos es el siguiente: Convertir un número
binario en su equivalente decimal.
uses crt;
type TBin = array[1..8]of byte;
var
NBin
: TBin;
NDec
: integer;
PesoDig : integer;
i
: byte;
begin
clrscr; highvideo; PesoDig:=128; NDec:=0;
for i:=8 downto 1 do begin
write('NBin ',i,'=');
readln(NBin[i]);
NDec:=NDec+NBin[i]*PesoDig;
PesoDig:=PesoDig DIV 2;
end;
write('El binario ingresado fue ');
for i:=8 downto 1 do write(NBin[i]);
writeln;
writeln('Su equivalente decimal es ',NDec);
readkey;
end.
Clase Teórica Nro 9
Pág 6/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
Como en toda base de numeración los dígitos de mayor peso son los que están más a
la izquierda, hemos trabajado con un lazo for decreciente (downto) de 8 hasta 1. Recuerde que los pesos binarios son:
Pesos
128 64
32
16
8
4
2
1
--------------------------------------------------------------------------8
7
6
5
4
3
2
1
Posiciones
En realidad a la primera posición es cero, pero a fin de no trabajar con potencias de 2,
le llamaremos 1. Además recuerde que los dígitos binarios sólo pueden ser 1’s o 0’s.
Imaginemos que ingresamos:
11001011
Para obtener su equivalente decimal tendríamos que hacer:
1x 128 + 1 x 64 + 0 x 32 + 0 x 16 + 1 x 8 + 0 x 4 + 1 x 2 + 1 x 1
o sea cada dígito por su correspondiente peso (como se vio en la primera clase).
Esta sumatoria de productos se halla implementada dentro del lazo for. Analícela.
Producto matricial de dos matrices.
Si bien las reglas de este producto no son complicadas, hay que trabajar un poco con
los lazos. En primer lugar dos matrices cualesquiera no pueden multiplicarse matricialmente salvo que cumplan con la siguiente condición:
Cantidad de filas de la segunda matriz = Cantidad de columnas de la primera.
x
a [4,4]
=
b [4,2]
c [4,2]
c[1,1] = a[1,1] x b[1,1] + a[1,2] x b[2,1] + a[1,3] x b[3,1] + a[1,4] x b[4,1]
c[1,2] = a[1,1] x b[1,2] + a[1,2] x b[2,2] + a[1,3] x b[3,2] + a[1,4] x b[4,2]
c[2,1] = a[2,1] x b[1,1] + a[2,2] x b[2,1] + a[2,3] x b[3,1] + a[2,4] x b[4,1]
c[2,2] = a[2,1] x b[1,2] + a[2,2] x b[2,2] + a[2,3] x b[3,2] + a[2,4] x b[4,2]
etc.
Clase Teórica Nro 9
Pág 7/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
Ahora tenemos que implementar un código Pascal para que esto se realice automáticamente.
uses crt;
const DIM1
DIM2
DIM3
DIM4
=
=
=
=
4;
4;
4;
2;
type TMat1 = array[1..DIM1,1..DIM2]of integer;
TMat2 = array[1..DIM3,1..DIM4]of integer;
var
a
b
c
i,j,k
S
Fila
Col
:
:
:
:
:
:
:
TMat1;
TMat2;
TMat2;
byte;
integer;
byte;
byte;
begin
clrscr; highvideo; randomize;
{ --- Carga la matriz a[ ] ----- }
for i:=1 to DIM1 do begin
for j:=1 to DIM2 do begin
a[i,j]:=random(11);
write(a[i,j]:3);
end;
writeln;
end;
writeln; writeln;
{ --- Carga la matriz b[ ] ----- }
Fila:=1; Col:=20;
for i:=1 to DIM3 do begin
for j:=1 to DIM4 do begin
b[i,j]:=random(11);
gotoxy(Col+(j-1)*3,Fila+i-1); write(b[i,j]);
end;
writeln;
end;
{ --- realiza el producto matricial de a x b }
Fila:=1; Col:=30;
Clase Teórica Nro 9
Pág 8/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
for i:=1 to DIM1 do
for k:=1 to DIM4 do begin
S:=0;
for j:=1 to DIM2 do
S:=S+a[i,j]*b[j,k];
c[i,k]:=S;
gotoxy(Col+(k-1)*5,Fila+i-1); write(c[i,k]);
end;
readkey;
end.
Si este problema ha sido correctamente comprendido, no habrá dificultad para los próximos ejemplos.
Código de colores para resistencias eléctricas.
En electrónica los valores de las resistencias suelen (o solían) estar codificadas en
bandas de colores que tenían el siguiente significado:
Banda1
Banda2
Bada3
Primera cifra.
Segunda cifra.
Número de ceros a agregar (multiplicador).
Los colores establecidos eran los siguientes:
negro
marrón
rojo
naranja
amarillo
verde
celeste
lila
gris
blanco
0
1
2
3
4
5
6
7
8
9
qué mejor que colocar estos valores dentro de un vector de 10 domicilios:
var
Cod : array[0..9]of string[12];
begin
Cod[0]:=’negro’;
Cod[1]:=’marron’;
Cod[2]:=’rojo’;
etc.
Clase Teórica Nro 9
Pág 9/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
De esta manera cuando necesitemos un código buscamos el color y nos quedamos
con el índice.
uses crt;
type TVectCod = array[0..9]of string[12];
var
Cod
B1
B2
B3
i
Mult
Val1
Val2
Val3
R
:
:
:
:
:
:
:
:
:
:
TVectCod;
string[12];
string[12];
string[12];
integer;
longint;
integer;
integer;
integer;
longint;
begin
clrscr; highvideo;
Cod[0]:='negro';
Cod[1]:='marron';
Cod[2]:='rojo';
Cod[3]:='naranja';
Cod[4]:='amarillo';
Cod[5]:='verde';
Cod[6]:='celeste';
Cod[7]:='lila';
Cod[8]:='gris';
Cod[9]:='blanco';
B1:='rojo';
B2:='amarillo';
B3:='verde';
for i:=0 to 9 do begin
if(B1=Cod[i])then Val1:=i;
if(B2=Cod[i])then Val2:=i;
if(B3=Cod[i])then Val3:=i;
end;
Mult:=1;
for i:=1 to Val3 do Mult:=Mult*10;
R:=(Val1*10+Val2)*Mult;
writeln('R = ',R,' Ohms');
readkey;
Clase Teórica Nro 9
Pág 10/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
end.
(* --- Ejemplo ARR_04.PAS
Cargar aleatoriamente una matriz de 5 x 7 con enteros entre
10 y 50 y mostrarla en pantalla. A continuación realizar la
suma de los términos de cada fila mostrando dichos resultados a continuación de cada fila en pantalla.
¿Cual fue la máxima suma obtenida?
¿En cual fila se produjo?
Indicar estos dos últimos ítems un poco mas abajo de la matriz.
------------------------------------------------------ *)
uses crt;
const DIM1 = 5;
DIM2 = 7;
type TMat = array[1..DIM1,1..DIM2]of integer;
var
Mat
Smax
Sparc
FSmax
i,j
:
:
:
:
:
TMat;
integer;
integer;
byte;
byte;
{ suma maxima
}
{ suma parcial
}
{ fila para suma maxima }
begin (* main *)
clrscr; highvideo; randomize;
Smax:=0;
for i:=1 to DIM1 do begin
Sparc:=0;
for j:=1 to DIM2 do begin
Mat[i,j]:=10+random(51);
write(Mat[i,j]:3);
Sparc:=Sparc+Mat[i,j];
end;
write('S=':8,Sparc);
writeln;
if(Sparc>Smax)then begin
Smax:=Sparc;
FSmax:=i;
end;
end;
writeln;
writeln('Suma maxima = ',Smax);
writeln('Fila de Smax = ',FSmax);
readkey;
Clase Teórica Nro 9
Pág 11/12
INFORMATICA CBI – 2013
Dictado : Ing. Juan Manuel Conti
end.
Clase Teórica Nro 9
Pág 12/12
Descargar