Tipos enumerados en Pascal

Anuncio
Apunte del curso ALGORITMOS y PROGRAMACIÓN (FI-UBA, Prof. Ing. F. J. LAGE, J. T. P.
Ing. Z. CATALDI; A.T.P. Srta. A Pauluzzi, Sr. C Corradino, Sr. F Gómez
SUBRANGO ENUMERADOS CONJUNTOS
SUBRANGO:
Un tipo subrango se define a partir de un tipo ordinal, especificando dos valores constantes de ese tipo, que a partir de aquí serán el límite inferior y superior del conjunto de datos de esa clase. Un tipo subrango es un por ser un subconjunto de un tipo ordinal es también ordinal, y sus valores se ordenan de la misma forma que están ordenados en el tipo patrón del cual derivan.
Ejemplos
1 ..10
este tipo subrango consta de los elementos 1,2,3,4,5,6,7,8,9,10
’F’ .. ’I’
este subrango consta de los caracteres ’F’, ’G’, ’H’, ’l’
’a’ .. ’z’
este subrango consta de los caracteres ’a’ hasta ’z’
’0’ .. ’9’
este subrango consta de los caracteres ’0’ a ’9’
Para operar con el tipo subrango, se pueden hacer de dos maneras distintas.
a) Creando un tipo y luego asignándolo
a una variable
b) Definiéndolo directamente en la declaración de variables
type
var
IntervaloEnteros = -100..100;
Grande : integer;
var
Reducido : -100..100;
Grande : integer;
Reducido : IntervaloEnteros;
El tipo subrango es esencialmente utilizado para dos fines:
1. Mejorar la legibilidad y la comprensión
2. Aumentar la fiabilidad de los programas, ya que Pascal detecta si un valor recibe un valor fuera
del intervalo declarado.
El tipo subrango puede ser leído de teclado como cualquier otra tipo de variable (Read o ReadLn), y
presentado a través de pantalla por medio de los procedimientos correspondientes (Write, WriteLn).
Compatibilidad de tipos:
Los tipos subrangos y los tipos de donde proceden, son compatibles, en el sentido de que cualquier tipo de subrango pertenece al patrón.
En el ejemplo anterior es legítima la sentencia:
Grande := Reducido;
También es legítimo el código de programa
ReadLn (Grande);
Página 1 de 11
Reducido := Grande;
Sin embargo, si al leer con Readln (Grande) se toma para Grande un valor de 500 (fuera del rango IntervaloEnteros), la sentencia de aplicación
Reducido := Grande
produce un mensaje de error.
Como ya se ha dicho un uso importante de los tipos subrangos es detectar ciertos errores de programación o carga de datos. Si se espera que una variable tome valores siempre en un cierto rango, entonces
se debe declarar esa variable que adopte el tipo subrango. De este modo, si la variable de tipo subrango
toman un valor fuera del rango especificado, se producirá un mensaje de error.
10.3.4. La directiva del compilador R
Turbo Pascal no siempre produce un mensaje de error cuando el valor de un tipo subrango está fuera
de su rango definido. Sin embargo, puede tener la posibilidad de visualizar dichos mensajes de error, insertando la siguiente línea en el archivo que contenga su programa:
($R+)
Esta línea se denomina directiva del compilador. Su valor por defecto (desactivada) es $R-, que no
realiza la verificación de los índices del subrango, pero que por el contrario aumenta la velocidad de ejecución. Durante la fase de depuración y puesta a punto de un programa es aconsejable utilizar la directiva
$R+, insertándola al principio del programa.
ENUMERADOS:
Pascal permite otro tipo de dato ordinal denominado tipo enumerado. Estos tipos de datos son definidos por el usuario. Un tipo enumerado se compone de un conjunto de valores referenciados por identificadores. Estos valores constituyen una lista de identifica- dores de constantes que el programador debe indicar
en la parte del programa reservada a las declaraciones. Eligiendo adecuadamente nombres significativos
para los identificadores se pueden hacer programas más fáciles de leer.
Ejemplos
type
Vehiculos = (avion, barco, tren, automovil, moto, colectivo);
Frutas = (frutillas, manzana, pera, naranja, duraznos);
Estos tipos pueden ser asignados a variables. Así, por ejemplo, se puede declarar
Var
Transporte : Vehiculos;
Postre : Frutas;
Características
§ Un tipo de dato enumerado es un tipo ordinal cuyo orden se indica por la disposición de los valores en la definición.
§ El número de orden de cada elemento comienza en 0 para el primer elemento.
type
Arcoiris = (Verde, Amarillo, Rojo, Azul, Verde);
Página 2 de 11
Verde es el elemento número 0. Amarillo es el elemento número 1. Miércoles es el elemento tercero
(3).
§ Las variables de tipo enumerado sólo pueden tomar valores de estos tipos.
type
Dia (lunes, martes, miercoles, jueves, viernes, sabado, domingo);
var
Semana : dia;
Las sentencias siguientes son válidas:
Semana := miercoles;
while Semana = jueves do
§ Los únicos operadores que pueden acompañar a los enumerados son los operadores de relación
y de asignación.
lunes < martes verdadera
jueves < viernes verdadera
La expresión
Colegio < martes
produce un error de sintaxis, ya que los valores mostrados se asocian con dos tipos diferentes. El
operador de asignación puede definir el valor de una variable cuyo tipo es un tipo enumerado.
Dado que están ordenados los valores de un tipo enumerado, pueden ser comparados con la ayuda
de operadores relacionales. Mediante las sentencias selectivas y repetitivas es posible dar gran flexibilidad a
su lenguaje.
Ejemplo a)
Ejemplo b)
if hoy < sabado then
While hoy <> domingo do
Write (’Dia laborable’)
Ejemplo c)
Else
For hoy := lunes to viernes do
Write (’Fin de semana’);
§ Los procedimientos de entrada/salida no pueden leer o escribir datos de tipo enumerado.
Write (jueves); producirá un error
ReadLn (jueves); producirá un error
Si se desea obtener una salida se debe utilizar una sentencia Case
Case hoy of
lunes
martes
miercoles
jueves
: Write ("Lunes");
: Write ("Martes");
: Write ("Miércoles");
: Write ("Jueves");
Página 3 de 11
viernes
sabado
: Write ("Viernes");
: Write ("Sábado")
else
Write ("Domingo")
end;
§ Un valor no puede figurar en dos tipos enumerados diferentes.
§ Los tipo enumerado no pueden leerse o escribirse en los archivos de texto.
Subrangos de tipo enumerados
Se pueden declarar subrangos de tipo enumerado
Por ejemplo
type
mes = (enero, febrero, marzo, abril, mayo, junio, julio, agosto, septiembre, octubre, noviembre, diciembre);
primavera
verano
otonio
invierno
= octubre .. diciembre;
= enero.. marzo;
= abril .. junio;
= julio .. septiembre;
var
mensual : mes;
vendimia : otonio;
vendimia := abril;
vendimia := julio;
sentencia válida
sentencia no válida
Funciones Ordinales
Los tipos de datos ordinales como ya nos hemos referido, cada valor tiene un único predecesor (excepto el primero) y un único sucesor (excepto el último). Basándose en esta propiedad Pascal incorpora
tres funciones predefinidas. Ord, Pred y Succ.
Ord
Determina la posición relativa de un elemento en la serie, las series no numéricas comienzan por la
posición 0 (cero).
Página 4 de 11
Por ejemplo:
type
mes = (enero, febrero, marzo, abril, mayo, junio, julio, agosto, septiembre, octubre, noviembre, diciembre);
var
{* definición de las variables *}
A : Integer;
begin
{* Comienzo del programa *}
......
A := ord(junio);
Writeln ('El ordinal de Junio es: ',A); {* Salida del resultado *}
A debe ser de tipo ordinal (byte o integer), el resultado de esta carrera es 5.
Pred y Succ
Pred devuelve el predecesor del argumento y Succ devuelve el sucesor del argumento.
Pred (marzo) ⇒ febrero
Succ (marzo) ⇒ abril
Pred (enero) ⇒ indefinido
Succ (diciembre) ⇒ indefinido
Aunque no se vea a simple vista su utilidad estas funciones pueden ser aplicadas para ejemplos como el siguiente.
While mensual <= diciembre do
begin
A := Ord (mensual);
mensual := Succ(mensual);
end;
CONJUNTOS
Es otro tipo de datos estructurado con el que se puede operar en Pascal. es el conjunto (set). Una variable de tipo set se denomina conjunto. El concepto es idéntico al matemático, y con este tipo de datos se
puede realizar las mismas operaciones que las vistas en matemática (unión, intersección, etc.). En Pascal
el conjunto de elementos se representan entre corchetes y separados por comas El máximo número de
elementos de un conjunto es 256.
Como en el álgebra existe el conjunto vacío, es aquel que no contiene ningún elemento.
Declaraciones de tipos de datos conjuntos
Para declarar o definir variables tipo conjunto, se deberá definir en función de un tipo base que deberá
ser ordinal.
Página 5 de 11
Ejemplos
type
mes = (enero, febrero, marzo, abril, mayo, junio, julio, agosto, septiembre, octubre, noviembre, diciembre);
meses = set of mes;
digitos = set of byte; (no acepta otro tipo de enteros)
caracteres = set of char;
var
Periodo, Cuatrimestre, Trimestre : meses;
Posicion: digitos;
El conjunto como cualquier otra variable parte de una condición de vacío. Los elementos pueden ser
colocados en los conjuntos utilizando una sentencia de asignación.
Periodo := [ ];
Posicion := [3, 5, 6, 8]
Cuatrimestre := [abril..julio];
En el primer caso se le asignó será un conjunto vacío, en el segundo de los casos estará compuesto
por esos cuatro elementos (3, 5, 6, 8), y en el último de los casos serán los meses (abril, mayo, junio, julio).
Dos tipos de conjuntos son compatibles, si tienen los tipos base compatibles. En este caso sus variables representativas se pueden utilizar en sentencias de asignación.
Periodo := Trimestre := [ ];
Una variable de tipo conjunto se suele inicializar al conjunto vacío o al conjunto universal.
Include
A partir de la versión 7 de Pascal. Una de las formas para agregar un elemento a un conjunto es a través del procedimiento include.
Exclude
También es una modificación de la versión 7. Exclude es un procedimiento para eliminar un elemento
a un conjunto.
Ejemplos
Posicion :=[3, 5, 6, 8];
A := 15;
include(Posicion, 22);
include(Posicion, A);
exclude (Posicion, 22);
exclude (Posicion, A);
En ambos casos se da como parámetros el conjunto (Posicion) y el elemento a agregar o quitar. El
mismo puede darse como valor o como una variable, de esta última forma la variable debe ser de igual tipo
que el tipo base del conjunto.
Página 6 de 11
La relación In
Determina si un elemento pertenece o no a un conjunto. El resultado de evaluar la expresión relacional
puede ser true o false. El tipo de datos de elemento y la lista de elementos deben ser compatibles.
Ejemplo
if A in Posicion then
if 15 in Posicion then
La variable A y los elementos de Posicion deben ser compatibles.
OPERACIONES CON CONJUNTOS
En Pascal es posible realizar tres operaciones binarias sobre ellos que son: unión, intersección y diferencia.
Unión (+)
Las tres operaciones cumplen estrictamente las reglas del álgebra de conjuntos. Por lo tanto la unión
de dos conjuntos da como resultante otro conjunto que tiene por elementos a los elementos comunes y no
comunes de ambos conjuntos. La unión de conjunto se representa por el símbolo de la suma.
Alfa := [3, 5, 8, 14];
Beta := [2, 5, 9, 14, 22];
Capa := Alfa + Beta; ⇒
Capa = [2, 3, 5, 8, 9, 14, 22]
La unión es el segundo método para ingresar un elemento a un conjunto
Ejemplo
ReadLn(A);
Posicion := Posicion + [A]
Diferencia (-)
La diferencia entre dos conjuntos da otro conjunto que tiene por elementos, todos los elementos del
primer conjunto que no pertenecen al segundo. Se representa por el símbolo de la diferencia.
Capa := Alfa - Beta; ⇒
Capa = [3, 8]
Capa := Beta - Alfa; ⇒
Capa = [2, 9, 22]
La diferencia es el segundo método para sacar un elemento a un conjunto
Ejemplo
ReadLn(A);
Posicion := Posicion - [A]
Intersección (*)
La intersección entre dos conjuntos da otro conjunto que tiene por elementos, todos los elementos
comunes a ambos conjuntos. Se representa por el símbolo del producto.
Página 7 de 11
Capa := Alfa * Beta; ⇒
Capa = [5, 14]
COMPARACIÓN DE CONJUNTOS
Los conjuntos se pueden comparar entre sí mediante el uso de los operadores relacionales (=, <> , <
=, > =). Los operandos deben ser del mismo tipo base. El resultado de la comparación es un valor lógico:
true o false.
Igualdad de Conjuntos
Dos conjuntos son iguales, cuando sus tipos de base son equivalentes, y además todo elemento del
primer conjunto pertenece al segundo y todo elemento del segundo conjunto pertenece al primero.
Sub y Superconjunto
Un conjunto Alfa es subconjunto (esta incluido) de otro Beta, si todo elemento de Alfa pertenece a Beta, pero no todo elemento de Beta pertenece a Alfa. En dicho caso Beta será un superconjunto de Alfa
LOS CONJUNTOS COMO PARÁMETROS
Los conjuntos se pueden utilizar como parámetros de funciones y procedimientos. En el caso de una
función, se debe recordar que la misma devuelve un único valor, por lo tanto su tipo deberá ser un dato simple y no puede ser un conjunto.
Ejemplo
Realizar un programa que determine los números primos de entre 1 y N elegido por el usuario (menor
que 65536). Utilizando la Criba de Eratóstenes.
La idea de la criba es la siguiente:
Dado una serie ordenada de valores, por ejemplo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
se prueba cuales son múltiplos de dos y se los elimina de la serie
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
se busca el siguiente de la serie (3) y se elimina los múltiplos de él
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
y así sucesivamente.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
El último valor con que se prueba es con R el cual es la parte entera de la raíz cuadrada del mayor de
los valores de la serie.
Página 8 de 11
program Criba_de_Eratostenes;
{* Ejemplo de conjuntos *}
{* Desarrollo del Ing. Fernando J. LAGE *}
{* Septiembre 1998*}
uses
wincrt,windos; {* declaraciones de librerias, para correr bajo Windows *}
{* crt,dos;*} {* declaraciones de librerias, para correr bajo DOS *}
const
Enter = #13;
Ln = #13#10; {* Indica un salto de renglón *}
type
Valores = set of byte; {* Tipo conjunto *}
var
{* definición de las variables *}
Criba : Valores;
N, S: Byte;
h : char;
procedure ingresos;
begin
{* Comienzo del procedimiento de ingreso de valores *}
repeat
Write ('Ingrese un valor mayor que 0 y menor o igual 255 ');
Readln (N);
until (N>0) and (N<255)
end;
{* Fin del procedimiento ingreso*}
function Extremo(A:Byte):Integer; {función que devuelve la parte entera de la raíz cuadrada }
var
Raiz : Real;
begin
{* Comienzo de la función Extremo *}
Raiz := Sqrt(A);
Extremo := Trunc(Raiz);
end;
{* Fin de la función Extremo *}
Página 9 de 11
procedure Llenado(var Alfa : Valores; {* tipo conjunto *}
Beta : Byte);
var
i : Byte;
begin
{* Comienzo del procedimiento de llenado de valores *}
WriteLn (Ln,Ln,'Elementos del conjunto original : ');
For i := 1 to Beta do
begin
Write (i,' ');
Alfa := Alfa + [i] {* Agrega un elemento al conjunto *}
end
end;
{* Fin del procedimiento Llenado *}
function Multiplo(A,B:Byte):Boolean; {* Función que devuelve si un número es múltiplo o no *}
var
Mul : Byte;
begin
{* Comienzo de la función Extremo *}
Mul := ((B div A)*A);
Multiplo := Mul=B
end;
{* Fin de la función Extremo *}
procedure Primos(var Alfa : Valores; {* tipo conjunto *}
Beta, Gama: Byte);
var
i,j : Byte;
begin
{* Comienzo del procedimiento de búsqueda de valores no primos*}
WriteLn (Ln, Ln, 'Elementos del conjunto original : ');
For i := 2 to Gama do
If i in Alfa Then
For j := i+1 to Beta do
If j in Alfa then
If Multiplo(i,J) then
Alfa := Alfa - [j];
end;
{* Fin del procedimiento Primos *}
Página 10 de 11
procedure salidas (Beta :Valores); {* tipo conjunto *}
var
i : byte;
begin
{* Comienzo del procedimiento de egreso de valores *}
Writeln (' ',LN); {* Se deja renglones en blanco *}
For i := 1 to N do
if i in Beta then
begin
Write (' ',i); {* Salida del resultado *}
exclude (Beta,i)
end;
Writeln (' son primos'); {* Salida del resultado *}
Writeln (' ', Ln, Ln, Ln, Ln); {* Deja cinco renglones en blanco *}
writeln ('Presione un tecla para terminar'); {* Salida de mensaje *}
read(h);
ClrScr;
end;
{* Fin del procedimiento salidas*}
begin {* Comienzo del programa *}
{* Se limpia la pantalla *}
ClrScr;
{* Declaro al conjuto vacio *}
Criba := [];
{* Ingreso del extremo superior *}
Ingresos;
{* Llenado del conjunto *}
Llenado(Criba, N);
{* Cálculo de el extremo de búsqueda *}
S := Extremo(N);
{* Obtención de los números primos *}
Primos(Criba,N,S);
{* Salida de resultados *}
Salidas(Criba);
end. {* Fin del programa *}
Página 11 de 11
Descargar