12 Último

Programando desde 0: 11- Subrangos y Arreglos lineales.

      • 318
      • mensajes
      • miembro desde
      • 07/02/07
    26/01/2012
    #1 Programando desde 0: 11- Subrangos y Arreglos lineales.
    Introducción a los TIPOS definidos por el programador

    Lección 11: Subrangos y Arreglos lineales

    Introducción:

    Hasta ahora hemos visto como crear programas que puedan hacer una cosa u otra en función de ciertas condiciones, como hacer que repitan ciertas instrucciones también de forma condicional, entre otras cosas. En todos esos programas hemos usado variables de distintos tipos, sin embargo siempre han sido tipos primitivos de Pascal, o sea, los que ya están predefinidos por el lenguaje, tales como REAL, STRING, CHAR, INTEGER, etc. Sin embargo es posible que el programador defina tipos propios que pueden contener datos más complejos que simples números, caracteres o cadenas.

    Obviamente esto no es totalmente libre porque seguirá dependiendo de los tipos primitivos, pero dada nuestra imaginación podemos crear tipos realmente muy complejos y que contengan mucha información. Los posibles tipos que podemos definir nosotros mismos son:


    • Subrangos
    • Arreglos
    • Conjuntos
    • Enumerados
    • Registros
    • Punteros



    Todos excepto Punteros, al igual que los tipos primitivos, corresponden a tipos estáticos de Pascal. Esto significa que declarada una variable de uno de esos tipos se asignará de la memoria el espacio suficiente para albergar el mayor valor posible. Este espacio de memoria estará en uso aunque nosotros no usemos la variable declarada o aunque usemos solo una parte de la información que esta pueda guardar. Este espacio de memoria se asigna ya al compilar el programa, o sea, en tiempo de compilación. Esto no significa que al compilar el programa estemos ocupando nuestra RAM con las variables que el programa use, sino que al compilarlo se agregan las instrucciones que harán que el programa solicite esa memoria ya al ser ejecutado y la mantendrá siempre en uso hasta que se cierre.

    Los Punteros corresponden a un tipo dinámico. Esto es que, podremos pedir memoria cuando la necesitemos y devolverla cuando ya no la usemos, todo en tiempo de ejecución, pero este será el último tema de este curso.

    -------------------------------------------------------------------------------------

    Subrangos:

    Muy bien, el primer tipo a definir por el usuario que veremos es llamado subrango. Este es el tipo más sencillo de declarar. Consiste en crear un Subrango de uno de los tipos primitivos ordinales de Pascal. Por ejemplo, un Subrango de los enteros podrían ser los naturales, ya que estos son lo enteros de 0 en adelante (algunos los toman de 1 en adelante).

    Los tipos a definir se declaran antes que las variables pero luego que las constantes. Para ello debemos indicar mediante la palabra reservada TYPE que haremos declaración de tipos. Veamos un ejemplo de declaración de subrangos:

    Código:
    Type
       Naturales= 0..MAXINT;
       Mes= 1..12;
       Decimal= 0..9;
       Minusculas= 'a'..'z';
       Digito= '0'..'9';
       Mayusculas= 'A'..'Z';
    Aquí hemos declarado seis tipos Subrangos diferentes. Como ven la sintaxis es bien sencilla, luego de la palabra TYPE se declaran todos los tipos necesarios de esta manera:

    Identificador= valor_inicial..valor_final;

    En este ejemplo tenemos el tipo Naturales que contendrá valores enteros entre 0 y MAXINT. Luego está el tipo Mes que contendrá enteros entre 1 y 12. Decimal contendrá valores entre 0 y 9. Luego vemos tres subrangos de caracteres: Minusculas que contendrá los caracteres de la a a la z. Esto es porque las letras están ordenadas según la Tabla Ascii ascendentemente y sabemos que ‘a’<’z’. Digito contendrá los caracteres del '0' al '9'. Notar que Digito contiene los caracteres numéricos y Decimal los valores enteros de esos números. NO ES LO MISMO.
    Finalmente tenemos el tipo Mayusculas que contiene caracteres de la A a la Z.
    Dado que estos son tipos, para usarlos debemos declarar variables de ese tipo:

    Código:
    Type
       Naturales= 0..MAXINT;
       Mes= 1..12;
       Decimal= 0..9;
       Minusculas= 'a'..'z';
       Digito= '0'..'9';
       Mayusculas= 'A'..'Z';
       
    Var
       letraMin: Minusculas;
       numero: Naturales;
       letraMay: Mayusculas;
    Como ven es la misma sintaxis que para declarar una variable de tipo primitivo, le damos un identificador, dos puntos y luego el nombre del tipo. Esto significa que la variable letraMin podrá tomar valores de la a a la z ya que es del tipo Minusculas. Como el Subrango Minusculas corresponde a un Subrango de caracteres, letraMin se comportará como una variable char con la diferencia de que no podrá tomar valores fuera del rango indicado por Minusculas. Si esto sucede tendremos un error en tiempo de ejecución. Si han activado Range checking como se los indiqué al inicio del tutorial, el compilador verificará esto en la medida de lo posible y se los advertirá, pero no siempre podrá hacerlo. Por ejemplo, si ustedes hacen read(letraMin) el compilador no podrá asumir que el usuario puede ingresar un carácter fuera del rango y por tanto compilará correctamente, pero si hacen, letraMin:= ‘A’ les advertirá su error. Hay más casos de esto, pero lo verán en la práctica.

    Lo mismo sucede para los subrangos Decimal, Mes y Naturales, que son subrangos de integer. Las variables de estos tipos funcionarán como variables enteras con la diferencia de que deben tomar valores dentro de los rangos establecidos.
    Visto de esta manera no puedo incentivarlos mucho con el uso de los subrangos, sin embargo veremos que resultan útiles para definir Arreglos, que es el tema que viene a continuación.

    Lo que puedo decirles es que al definir un Subrango ustedes podrán estar seguros de que sus variables tendrán los valores adecuados, mas allá de que sean ustedes mismos quienes deban controlar esos valores.

    -------------------------------------------------------------------------------------

    Arreglos:

    Declaración:

    Muy bien, ahora sí se viene algo más interesante. Este es un tema muy importante y deberán aprenderlo bien, ya que los arreglos son estructuras usadas para casi todo y en la mayoría de los lenguajes.
    Un arreglo es una tabla compuesta por celdas que contienen, todas, valores de un mismo tipo.



    Ese es un ejemplo de un arreglo de enteros compuesto por nueve celdas. Cada celda tiene un valor distinto (pueden no serlo) y cada una es independiente de las demás. Como pueden ver todas las celdas están numeradas del 1 al 9. Estos valores son llamados subíndices y son los que usaremos para dirigirnos a una celda específica. Veamos primero cómo se declara un arreglo:

    Identificador= array[Subrango] of tipo;

    Debemos indicar un nombre para el arreglo (identificador), luego, al igual que para los subrangos va un signo de igual ( = ) y la palabra reservada array (arreglo en inglés) seguida inmediatamente por un Subrango entre paréntesis rectos [] el cual indicará la dimensión del arreglo (cuantas celdas tendrá). Luego colocamos la palabra reservada of y un tipo para los valores que habrá en cada celda. Este tipo puede ser uno primitivo de Pascal o uno definido anteriormente por el programador. Veamos algunos ejemplos:
    El arreglo dibujado arriba podría estar declarado como:

    Código:
    Arreglo1= array[1..9] of integer;
    En este ejemplo le dimos el nombre Arreglo1. Declaramos directamente entre los paréntesis rectos un Subrango. La dimensión de ese Subrango indica la dimensión del arreglo, en este caso el Subrango va de 1 a 9 por tanto contiene 9 elementos. Esto indica que el arreglo tendrá nueve celdas. Es importante notar que esto indica solo la dimensión del arreglo y no el tipo de datos que contendrá, o sea, Arreglo1 no contendrá datos que solo vayan de 1 a 9 sino que contendrá cualquier entero en sus celdas ya que su tipo está declarado luego de of y es integer.
    El Subrango entre paréntesis rectos, además de indicar cuántas celdas tendrá el arreglo, también indica cómo se numeran. Arreglo1 tendrá 9 celdas numeradas del uno al nueve, sin embargo, de haberse declarado

    Código:
    Arreglo1= array[10..19] of integer;
    sería igual al anterior solo que sus nueve celdas estarían numeradas del 10 al 19, o de haberse declarado de esta manera

    Código:
    Arreglo1= array[‘a’..’i’] of integer;
    seguiría teniendo nueve celdas solo que estarían identificadas de la a a la i.

    Lo más común es numerarlas del 1 en adelante y es lo recomendable.
    Tal como hemos declarado esos arreglos estamos declarando sus dimensiones con subrangos anónimos, o sea, declarando estos justo dentro de los paréntesis rectos sin darles nombre alguno. Sin embargo también es posible colocar dentro de estos paréntesis un Subrango ya declarado anteriormente. Por ejemplo:

    Código:
    Type
       Decimal= 0..9;
       Arreglo1= array[Decimal] of integer;
    Como ven, teniendo declarado antes el Subrango Decimal es posible utilizarlo para definir la dimensión y numeración del arreglo. En este caso Arreglo1 tendrá 10 celdas numeradas del 0 al 9.
    También es posible hacer esto

    Código:
    Type
    Decimal= 0..9;
    Arreglo1= array[Decimal] of Decimal;
    En este caso, el arreglo tiene 10 celdas numeradas del 0 al 9 y cada una puede contener datos del tipo Decimal. Siempre es posible utilizar algún tipo para definir otro sí y solo sí el tipo a utilizar está definido anteriormente. No sería posible utilizar Decimal para definir el arreglo si declaráramos este Subrango más abajo que el arreglo.
    Un arreglo es un tipo y por tanto va declarado luego de la palabra Type tal como se ve en estos dos ejemplos.
    Veamos ahora más ejemplos de arreglos:

    Código:
    Type
       rango = 33..90;
       arr1 = array [char] of integer; (* 256 celdas *)
       arr2 = array [33..90] of real;
       arr3 = array [integer] of char; (* demasiado grande! *)
       arr4 = array [rango] of boolean;
    Tenemos un Subrango de enteros que va de 33 a 90. Luego tenemos arr1 que es un arreglo de 256 celdas (cantidad total de caracteres) cuyos índices según la Tabla Ascii van del ‘ ’ a ‘ ’ (del primer elemento de la tabla hasta el último) donde cada cela puede contener cualquier entero. arr2 que es un arreglo de 57 celdas numeradas del 33 al 90 donde cada una puede contener cualquier real. Luego tenemos arr3 que pretendería ser un arreglo de unas 65536 celdas numeradas desde el -32768 hasta el 32767 donde cada una podría contener caracteres. Este es un arreglo exorbitantemente grande, ocuparía muchísima memoria y provocaría muchos problemas. Además no es para nada ético crear este tipo de estructuras.
    Finalmente tenemos arr4 que tiene 57 celdas numeradas del 33 al 90 donde cada una es un booleano que puede valer TRUE o FALSE.

    -------------------------------------------------------------------------------------

    Utilización de arreglos:

    Hasta ahora solo hemos visto como se declara un arreglo y lo que significan las distintas declaraciones, sin embargo hace falta trabajar con ellos, y su sintaxis es un poco distinta a lo que venimos acostumbrados. Veremos un primer ejemplo donde crearemos un arreglo de enteros de 10 celdas cuyos índices van del 1 al 10 y a cada celda le daremos el mismo valor que su índice, o sea, a la primera le daremos el valor 1, a la segunda el 2 y así sucesivamente:

    Código:
    1   PROGRAM arreglos;
    2
    3   Type
    4      arr= array[1..10] of integer;
    5
    6   Var
    7      arreglo1: arr;
    8
    9   BEGIN
    10 arreglo1[1]:= 1;
    11 arreglo1[2]:= 2;
    12 arreglo1[3]:= 3;
    13 arreglo1[4]:= 4;
    14 arreglo1[5]:= 5;
    15 arreglo1[6]:= 6;
    16 arreglo1[7]:= 7;
    17 arreglo1[8]:= 8;
    18 arreglo1[9]:= 9;
    19 arreglo1[10]:= 10;
    20 END.
    En la línea 3 indicamos que comenzará la declaración de tipos para, luego, en la línea 4 declarar el tipo arr que será un arreglo de 10 celdas numeradas del 1 al 10 del tipo entero. Como arr es un tipo su propósito es declarar variables de ese tipo, por lo tanto en la línea 7 declaramos la variable arreglo1 del tipo arr. Podemos, al igual que con los tipos primitivos, declarar tantas variables como queramos de cualquier tipo que nosotros mismos definamos; en este caso tenemos solo una, pero podría tener más y cada una sería independiente.

    Bien, en la línea 9 comienza nuestro programa, el cual consta de diez líneas de asignación donde en cada una le damos un valor a cada celda del arreglo. Veamos esto con detalle, es bien sencillo. Cada celda del arreglo funciona como una variable independiente, por tanto, en ese arreglo tenemos diez variables del tipo integer. Para referirnos a una celda debemos dar el nombre de nuestro arreglo (no el nombre del tipo sino el de la variable de ese tipo) seguido por el índice entre paréntesis rectos de la celda a la que queremos ir. De este modo, en la línea 10, al escribir

    arreglo1[1]:= 1

    estamos diciendo que vaya a la primera celda de arreglo1 y le asigne el valor 1. La sintaxis genérica sería

    Variable_del_tipo_arreglo[indice_de_la_celda]

    con lo cual nos referiríamos a cualquier celda. Recordar que cada una es una variable independiente, por tanto esa declaración es como si fuera el nombre de la variable y funciona igual que cualquier otra variable, valga la redundancia.

    Todo lo que sigue del programa es asignar a las celdas restantes el valor que queremos y termina nuestro programa. Sin embargo no es muy útil tener que escribir instrucción por instrucción para dar un valor a cada celda. Imaginen un arreglo de 1000 celdas, tendríamos un programa de 1000 líneas solo en asignaciones. Veamos el mismo programa pero asignando los mismos valores a cada celda de una forma más inteligente:

    Código:
    1   PROGRAM arreglos;
    2
    3   Type
    4      arr= array[1..10] of integer;
    5
    6   Var
    7      arreglo1: arr;
    8      i: integer;
    9
    10 BEGIN
    11 For i:=1 to 10 do
    12    arreglo1[i]:= i;
    13 END.
    Hemos sustituido las 10 líneas de asignación por una instrucción FOR que va de 1 a 10. Fíjense que hemos colocado la variable de control i dentro los paréntesis rectos que indican el índice de nuestras celdas. De este modo, cuando i valga 1 estaremos hablando de la primera celda, cuando i pase a valer 2 estaremos hablando de la segunda celda, y así sucesivamente hasta 10. En este caso hemos asignado a cada celda el mismo valor de su índice, pero esto podría no ser así. Este arreglo dibujado sería:



    Ahora veamos lo mismo pero asignando el doble del índice a cada celda:
    Código:
    1   PROGRAM arreglos;
    2
    3   Type
    4      arr= array[1..10] of integer;
    5
    6   Var
    7      arreglo1: arr;
    8      i: integer;
    9
    10 BEGIN
    11 For i:=1 to 10 do
    12    arreglo1[i]:= i*2;
    13 END.
    De este modo arreglo1 ahora quedaría así:



    Dentro de los paréntesis rectos que indican el índice del arreglo es posible, como hemos visto ya, colocar el valor del índice, una variable del tipo correcto o, como no hemos visto aún, una expresión que dé cómo resultado un valor del tipo correcto y que esté dentro del rango de índices posibles.

    Es muy importante que lo que esté dentro de los paréntesis rectos nunca exceda el rango en que está numerado el arreglo. Si en este ejemplo nosotros escribiéramos

    Código:
    For i:=1 to 11 do
    arreglo1[i]:= i*2;
    se produciría un error cuando i alcanzara el valor 11 y el programa se cerraría abruptamente ya que la celda 11 no existe. Si han activado Range checking lo más probable es que el compilador les avise antes, pero esto no es siempre seguro ya que no siempre es detectable que podemos estar saliéndonos del arreglo.

    Veamos un nuevo ejemplo del mismo programa, solo que ahora los índices serán caracteres y a cada celda le
    asignamos el valor del ordinal de su índice. No olviden que el arreglo es de enteros.

    Código:
    1   PROGRAM arreglos;
    2
    3   Type
    4      arr= array[‘a’..’j’] of integer;
    5
    6   Var
    7      arreglo1: arr;
    8      i: char;
    9
    10 BEGIN
    11 For i:=’a’ to ‘j’ do
    12    arreglo1[i]:= ord(i);
    13 END.
    De este modo nuestro arreglo quedaría así:



    -------------------------------------------------------------------------------------

    Hacer WRITE y READ de un arreglo:

    Si quisiéramos desplegar un arreglo en la pantalla, o sea, que se nos muestren todos sus valores, debemos escribir celda por celda. En el ejemplo anterior teníamos el arreglo llamado arreglo1. Como primer impulso para escribirlo en pantalla uno tendería a hacer algo como esto

    Código:
    write(arreglo1);
    y sin embargo eso no es posible. De hacerlo tendrán un error en tiempo de compilación en el cual el compilador se les quejará por no poder escribir o leer variables de ese tipo. Esto es porque un arreglo es una estructura de datos y no un valor específico. Por este motivo es que debemos escribir celda por celda. No se olviden que cada celda es como una variable más y funciona del mismo modo. Veamos entonces como mostrar el arreglo de nuestro ejemplo anterior:

    Código:
    1   PROGRAM arreglos;
    2
    3   Type
    4      arr= array[‘a’..’j’] of integer;
    5
    6   Var
    7      arreglo1: arr;
    8      i: char;
    9
    10 BEGIN
    11 For i:=’a’ to ‘j’ do
    12    arreglo1[i]:= ord(i);
    13
    14 For i:=’a’ to ‘j’ do
    15    Write(arreglo1[i],’ ‘);
    16 END.
    La única diferencia entre este programa y el anterior es que agregamos un FOR que en cada iteración escribe el valor de una de las celdas. Verifiquen esto ustedes mismos.

    Ejercicio: Modifiquen este programa para que con un solo FOR asigne los valores al arreglo y lo muestre en pantalla.

    Del mismo modo, si quisiéramos hacer read de un arreglo para que el usuario ingrese los valores de cada celda debemos hacerlo para cada una por separado.

    Ejercicio: Realicen un programa en el cual exista un arreglo de enteros de cinco celdas de modo que el usuario sea quién ingrese los valores para cada celda. Deben utilizar una instrucción FOR para ello.

    ===============================================

    Declaración anónima de un arreglo:

    Los arreglos que hemos visto hasta ahora los hemos declarado como tipos de modo que podemos declarar muchas variables de ese tipo. Sin embargo, a veces sucede que sabemos que vamos a usar un único arreglo en nuestro programa y nada más. Dado este caso no es necesario declarar el arreglo como tipo sino hacerlo de forma anónima, directamente como variable. Veamos esto con el programa anterior ya que tenemos un único arreglo en este:

    Código:
    1   PROGRAM arreglos;
    2 
    3   Var
    4      arreglo1: array[‘a’..’j’] of integer;
    5      i: char;
    6
    7   BEGIN
    8   For i:=’a’ to ‘j’ do
    9      arreglo1[i]:= ord(i);
    10
    11 For i:=’a’ to ‘j’ do
    12      Write(arreglo1[i],’ ‘);
    13 END.
    Como ven este programa es igual al anterior solo que hemos quitado la declaración de tipos y hemos declarado el arreglo directamente como variable. De este modo solo se usará como arreglo1 y no como tipo por lo cual no podremos declarar variables como en los casos anteriores.

    No está mal si declaran siempre los arreglos como tipo, pero tengan en cuenta que un arreglo como tipo ocupa más memoria que uno declarado anónimamente. Si han declarado un tipo array el programa guardará memoria para “recordar” que existe un tipo definido por ustedes y qué datos puede contener y luego también guardará memoria para cada variable que declaren de ese tipo. Si lo hacen de forma anónima solo guardará memoria para esa variable y punto.

    Un programa que utiliza mucha memoria es menos eficiente, al igual que uno que realiza demasiadas instrucciones o tareas. Siempre es importante tratar de que el programa haga el menor trabajo posible para que sea más veloz y requiera menos recursos de la computadora para trabajar.

    Yo no voy a dedicarme ahora a enseñarles acerca de la eficiencia de los programas ya que esta parte del curso está dirigida a personas que recién están aprendiendo, pero ya vayan teniendo en cuenta que este es un aspecto muy importante.

    De todos modos en algunos casos nombraré la mejor forma de realizar una tarea eficientemente.
    -------------------------------------------------------------------------------------

    Recorriendo arreglos:

    Ya sabemos como crear un arreglo y acceder a sus celdas para asignarles valores, leer estos desde la entrada o escribirlos. También sabemos que cada celda funciona como una variable independiente y que siempre podemos acceder a la que queramos si sabemos como están numeradas las celdas. Es por esto que conviene siempre que los índices vayan de 1..N, o sea de 1 hasta N donde N es la cantidad de celdas del arreglo. Esto ayuda a evitar confusiones y hace todo mucho más entendible. Sin embargo pueden hacerlo de otra manera si consideran que para cierto caso les resulta más útil.

    Muchas veces resulta necesario recorrer un arreglo, ya sea para buscar un elemento de él o para trabajar de algún modo con los valores de sus celdas, de otro modo ¿para qué lo habríamos creado entonces?
    Aunque les dejé esto como ejercicio, espero lo hayan hecho antes de llegar aquí, veremos un ejemplo donde el usuario ingresa 10 valores enteros para un arreglo y luego nosotros desplegaremos éstos para mostrárselos y además le mostraremos la suma de ellos:

    Código:
    1   PROGRAM sumaCeldas;
    2
    3   Const
    4      N= 10; //Dimensión del arreglo.
    5
    6   Type
    7      arr= array[1..N] of integer;
    8
    9   Var
    10    arreglo1: arr;
    11    i, suma: integer;
    12
    13 BEGIN
    14 //Mensaje para el usuario.
    15 write('Ingresa ‘,N,’ enteros: ');
    16
    17 //Leemos un valor para cada celda.
    18 For i:=1 to N do
    19    read(arreglo1[i]);
    20
    21 //Dejamos una línea en blanco.
    22 writeln;
    23
    24 //Mensaje al usuario. Mostramos su ingreso.
    25 write('Usted ha ingresado: ');
    26 For i:=1 to N do
    27    write(arreglo1[i],' ');
    28
    29 //Iniciamos suma en 0 ya que aún no hemos sumado nada.
    30 suma:=0;
    31
    32 //Recorremos todo el arreglo sumando los valores a suma.
    33 For i:=1 to N do
    34    suma:= suma + arreglo1[i];
    35
    36 //Mostramos el resultado al usuario.
    37 writeln;
    38 writeln('La suma de los valores es: ',suma);
    39 END.
    Lo primero a destacar en este ejemplo es el uso de la constante N cuyo valor es 10. Es simplemente la que usaremos para declarar el Subrango que declara la dimensión del arreglo. De este modo la usaremos también en las iteraciones FOR para recorrer todas las celdas del arreglo. Si luego debiéramos modificar nuestro programa para que el usuario ingrese 20 valores en vez de 10 solo debemos cambiar el valor de N en su declaración de la línea 4 y todo funcionará perfectamente. De lo contrario deberíamos cambiar un 10 por un 20 cada vez que iteráramos con el arreglo, al declararlo, etc.

    En la línea 17 tenemos un FOR que leerá un valor para cada celda del arreglo. Dada esa declaración el usuario puede ingresar de a un valor he ir presionando enter, o ingresar los 10 valores separados por espacio en una misma línea y presionar enter al final. Esto es posible ya que hemos usado el procedimiento read que lee un valor y deja el cursor en la misma línea. De haber usado readln deberíamos ingresar un valor por línea.
    Les dejo el resto del programa a ustedes.

    Ahora veremos un ejemplo donde el usuario ingresa 10 valores enteros en un arreglo y el programa le mostrará el mayor de todos ellos:

    Código:
    1   PROGRAM arreglos;
    2
    3   Const
    4      N= 10; //Dimensión del arreglo.
    5
    6   Type
    7      arr= array[1..N] of integer;
    8
    9   Var
    10    arreglo1: arr;
    11    i, mayor: integer;
    12
    13 BEGIN
    14 //Mensaje para el usuario.
    15 write('Ingresa ',N,' enteros: ');
    16
    17 //Leemos un valor para cada celda.
    18 For i:=1 to N do
    19    read(arreglo1[i]);
    20
    21 //Dejamos una línea en blanco.
    22 writeln;
    23
    24 //En un principio el mayor valor es el primero.
    25 mayor:= arreglo1[1];
    26
    27//Ahora recorremos el resto del arreglo buscando el mayor valor.
    28 For i:=2 to N do
    29 begin
    30    If arreglo1[i]>mayor then
    31       mayor:= arreglo1[i];
    32 end;
    33
    34 //Informamos al usuario.
    35 writeln('El mayor valor ingresado es: ',mayor);
    36 END.
    Lean ustedes mismos este código. Seguro son capaces de entenderlo muy bien.

    -------------------------------------------------------------------------------------

    Búsqueda de un elemento:

    En este ejemplo veremos un programa en el que el usuario ingresa 10 enteros que guardaremos en el arreglo y luego le pediremos que ingrese otro valor. Buscaremos ese valor en el arreglo. Si está ahí lo notificaremos y en caso contrario notificaremos que no está:

    Código:
    1   PROGRAM BusquedaArreglo;
    2
    3   Const
    4      N= 10; //Dimensión del arreglo.
    5
    6   Type
    7      arr= array[1..N] of integer;
    8
    9   Var
    10    arreglo1: arr;
    11    i, valorBuscado: integer;
    12    exito: boolean;
    13
    14 BEGIN
    15 //Mensaje para el usuario.
    16 write('Ingresa ',N,' enteros: ');
    17
    18 //Leemos un valor para cada celda.
    19 For i:=1 to N do
    20    read(arreglo1[i]);
    21
    22 //Dejamos una línea en blanco.
    23 writeln;
    24
    25 //Leemos el valor a buscar en el arreglo.
    26 write('Ingresa el valor que deseas buscar: ');
    27 readln(valorBuscado);
    28
    29 //Inicializamos nuestra variable índice en 0.
    30 i:=0;
    31 {Iteramos hasta encontrar el valor o hasta
    32 recorrer todo el arreglo sin hallarlo}
    33 Repeat
    34    //Aumentamos un índice.
    35    i:= i + 1;
    36    exito:= arreglo1[i]=valorBuscado;
    37 Until (exito) or (i=N);
    38
    39 writeln;
    40
    41 //Mostramos el mensaje correspondiente.
    42 If exito then
    43    writeln('El valor está en el arreglo.')
    44 else
    45    writeln('El valor no está en el arreglo.');
    46 END.
    Lo importante aquí está a partir de la línea 30 donde inicializamos i en 0 ya que será nuestro índice. En la línea 33 declaramos un REPEAT que aumentará nuestro índice de búsqueda y luego se fijará si el valor buscado es igual al de la celda en que estamos posicionados. En ese caso exito será true y la iteración terminará. En caso contrario volveremos a aumentar i en 1 y nos fijaremos en la nueva posición. La iteración terminará al encontrar el elemento o al recorrer todo el arreglo sin hallarlo.

    Es importante destacar el uso del REPEAT aquí. Como primera cosa sabemos que iteraremos al menos una vez ya que debemos fijarnos al menos en la primera celda del arreglo, por eso usé un REPEAT y no un WHILE.
    Alguno podrá preguntarse ¿y por qué no usaste un FOR para recorrer el arreglo como has hecho hasta ahora? Bien, veamos como quedaría ese trozo de código sin es vez de REPEAT fuera FOR

    Código:
    For i:=1 to N do
       exito:= arreglo1[i]=valorBuscado;
    
    If exito then
       Writeln(‘El valor está en el arreglo.’)
    Else
       Writeln(‘El valor no está en el arreglo.’);
    Con el FOR recorreremos todo el arreglo siempre. La bandera booleana se volverá true al hallar el elemento.
    Funciona perfectamente al igual que el REPEAT, ahora piensen esto. Imaginen que tenemos un arreglo de 500 celdas y el valor que buscábamos estaba en la celda número 86. Con el REPEAT recorreremos solo las primeras 86 celdas del arreglo y nos detendremos ya que al encontrar el elemento no nos interesa lo demás. Con el FOR, al encontrar el elemento la bandera será true pero aún así recorreremos las 500 celdas. Esto hace al programa trabajar de más cuando no es necesario y le resta mucha eficiencia. Piensen en un arreglo de miles y miles de celdas, por ejemplo, una base de datos de Google en donde están guardadas casi todas las webs del mundo. ¿Sería mejor recorrer la base de datos hasta encontrar el elemento o recorrerla toda siempre?
    Es importante que comprendan esto. Aunque ya les dije que no les haría mucho hincapié con esto de la eficiencia, también dije que en ciertas ocasiones mencionaría el modo de realizar ciertas tareas de la forma más eficiente posible.

    Deben notar que el programa anterior se detendrá ante el primer encuentro con el valor buscado sin interesarse en si se repite luego.
    Ahora les dejo una serie de ejercicios. No continúen con el tutorial hasta que sean capaces de realizarlos todos, o de lo contrario, no podrán con las lecciones que vendrán a continuación.

    -------------------------------------------------------------------------------------

    Ejercicios:

    Ejercicio1: Escriban un programa que lea diez enteros de la entrada estándar y guarde estos en un arreglo. El programa debe indicar el mayor de ellos y el índice de la posición en la que aparece, así como también, el menor de ellos y su posición. En caso de que se repita un valor mostrarán el índice de la primera celda en que aparezca.
    Asumimos que siempre se ingresan enteros en la entrada estándar.
    Ejemplo1:

    Código:
    Ingrese 10 enteros: 2 3 1 4 5 10 6 7 8 9
    El mayor entero es 10 en la posición 6
    El menor entero es 1 en la posición 3
    Ejemplo2:
    Código:
    Ingrese 10 enteros: 2 3 2 20 5 20 6 7 8 9
    El mayor entero es 20 en la posición 4
    El menor entero es 2 en la posición 1
    ---------------------------------------------------------------------

    Ejercicio2: Este ejercicio conlleva cierta dificultad, sobretodo porque trabajarán con dos arreglos a la vez, cada uno de distinto tamaño. Dada la definición de tipo para representar cadenas de caracteres de largo M y N :

    Código:
    CONST N = . . .;
      M = . . .; { M < N }
    . . .
    TYPE
       CadenaM = ARRAY[1..M] Of Char;
       CadenaN = ARRAY[1..N] Of Char;
    Implementen un programa que lea dos cadenas de la entrada estándar de largo M y N respectivamente, y determine si la primer cadena ocurre como parte de la segunda cadena. El programa debe funcionar para cualquier valor positivo que puedan tomar M y N, considerando la restricción M < N. Ustedes mismos definan los valores de las constantes.

    Ejemplo de entrada para N=6, M=3:
    tor
    totora


    Ejemplo de salida:
    El texto 'tor' se encuentra dentro del texto 'totora'.

    Ejemplo de entrada:
    tos
    totora


    Ejemplo de salida:
    El texto 'tos' no se encuentra dentro del texto 'totora'.

    ---------------------------------------------------------------------

    Ejercicio3: Tiene una dificultad similar al anterior. Dada la definición de tipo para representar cadenas de caracteres de largo N y M:

    Código:
    CONST N = . . .;
    M = . . .;
    . . .
    TYPE
       CadenaM = ARRAY[1..M] Of Char;
       CadenaN = ARRAY[1..N] Of Char;
    1. Escriban un programa que lea dos cadenas de largo M y N respectivamente, e imprima un mensaje en la salida estándar indicando si alguna letra en la primera palabra ocurre en la segunda.
    2. Escriban un programa que lea dos cadenas de largo M y N respectivamente, y determine si todas las letras en la primera palabra ocurren en la segunda.


    Como ya saben, siempre que un ejercicio les de verdaderos problemas no tienen más que preguntar. Siempre intenten todo lo que puedan y prueben bien sus programas antes de dar por terminado un ejercicio.

    Suerte, espero que comenten lo que les va pareciendo hasta ahora.
    a pabloo1261 le gusta esto.
  1. ¿Este tema te pareció interesante? Compártelo!

    ¿No es lo que buscabas? Intenta buscar un tema similar

    15 comentarios / 2064 Visitas

      • 24
      • mensajes
      • miembro desde
      • 30/12/11
    04/04/2012
    #2 Re: Programando desde 0: 11- Subrangos y Arreglos lineales.

    Hola de nuevo hacia tiempo que no podia continuar con las lecciones
    esta vez me ha frenado el ejercicio dos...
    tengo dos problemas:
    1- cuando hago leer el segundo texto solo me lee 4 letras y esta indicado que me lea 6 :S pero no se donde esta el fallo porque cuando le digo que me lea 3 si que lo hace bien
    (te dejo parte del codigo)

    Código:
    PROGRAM arraydoble;
    
    CONST
      M= 3;
      N= 6;
    
    TYPE
      cadenaM= array[1..M] of char;
      cadenaN= array[1..N] of char;
    
    VAR
      arreglo1: cadenaM;
      arreglo2: cadenaN;
      i,j: integer;
      
    
    BEGIN
      write('Escriba una palabra de ',M,' letras: ');
      For i:=1 to M do
            read(arreglo1[i]);
    
      writeln;
    
      write('Escriba otra palabra de ',N,' letras: ');
      For j:=1 to N do
            read(arreglo2[j]);
    y el segundo problema es que no se me ocurre como puede hacer que el programa detecte si las primeras letras introducidas estan en la segunda... bueno solo se me ocurre comparando celda por celda, pero no creo que sea esa la forma ya que no es muy eficiente :S

    alguna pista?

    Saludos
      • 318
      • mensajes
      • miembro desde
      • 07/02/07
    04/04/2012
    #3 Re: Programando desde 0: 11- Subrangos y Arreglos lineales.

    Intenta colocar un ReadLn luego del primer FOR, es decir, luego del WriteLn. Eso debe solucionar el problema de lectura que mencionas. En general, es necesario utilizar ReadLn luego de utilizar Read a fin de que ReadLn consuma el último caracter de la entrada, el cual es el caracter de fin de línea. No se ve, pero es el que marca el ENTER. Si no lo haces, tu siguiente Read lee el fin de línea y no los caracteres que escribes.

    Tu código quedaría así:

    Código:
    write('Escriba una palabra de ',M,' letras: ');   For i:=1 to M do         read(arreglo1[i]);    writeln;
      readln;
    {Aquí continuaría tu código}
    Tu segunda duda pues, no te queda otra que comprar celda a celda. Lamentablemente es así.
    No tienes otro modo de hacerlo más eficiente.

    Espero responder a tus preguntas, sino pues dímelo.

    Saludos.
      • 24
      • mensajes
      • miembro desde
      • 30/12/11
    06/04/2012
    #4 Re: Programando desde 0: 11- Subrangos y Arreglos lineales.

    mmmmm es decir:
    he de comprobar si arrarrelgo1[1]=arreglo2[1].... arreglo1[1]=arreglo2[2]... y asi sucesivamente
    :O vaya locura si cada palabra la ponemos de 10 letras xD

    Gracias por contestar

      • 37
      • mensajes
      • miembro desde
      • 04/07/09
    13/05/2012
    #5 Re: Programando desde 0: 11- Subrangos y Arreglos lineales.

    Buenas me aparecido genial este curso pero llegue ha este punto en el cual no me queda muy claro el comando array ; llegue entender la parte q son columnas las cuales cada una se le asigna un valor pero q funcion tienen como tal entendi perfectamente lo de la memoria type pero el array no me queda muy claro aun

      • 318
      • mensajes
      • miembro desde
      • 07/02/07
    28/05/2012
    #6 Re: Programando desde 0: 11- Subrangos y Arreglos lineales.

    No me queda muy clara tu duda

    • joseto1
      Invitado
    09/08/2012
    #7 Re: Programando desde 0: 11- Subrangos y Arreglos lineales.

    gracias por tenetme en cuenta para este curso

      • 35
      • mensajes
      • miembro desde
      • 04/04/11
    11/08/2012
    #8 Re: Programando desde 0: 11- Subrangos y Arreglos lineales.

    Hey que hay VLADY!!! regresando!!, bueno creo que esto de los arreglos se me da. Pero...en el ejercicio 1 se me complica poner en que posición estan los números. Pienso que se tiene que hacer una acción de "buscar" para posteriormente escribir la posision del número en cuestion (mayor y menor), solo que no encuentro como hacer, escribir esa acción.
    Por otra parte quiero preguntarte algo. Cuando hago los ejercicios y no recuerdo bien unas cosas o como en el ejercicio1 que ya habíamos hecho un programa de menor y mayor, los volvi a ver para hecharles un vistaso y ver cómo había desarrollado el código. La pregunta es: ¿eso está mal o es malo?, pienso que si hago eso estoy haciendo trampa o algo por el estilo je,je. Dime eso es valido? o es una costumbre que se me tiene que ir quitando.

    De antemano te agradezco tu sinceridad y que lleves tan bien el curso, es muy bueno y en tan solo 3 semanas (talvez 4) mira hasta donde he llegado y bien comprendido los temas.

    MUCHAS GRACIAS VLADY!!!! AMIGO!!!...

    P.D. te dejo el código para que le hechez un vistazo.

    Código:
    PROGRAM arregloej1;
    USES crt;
    
    CONST
       N = 10;
    
    VAR
       arreglo1: array[1..N] of integer;
       i, mayor, menor: integer;
    
    BEGIN
    clrscr;
       write('Ingresa ',N,' enteros: ');
       FOR i:=1 TO N DO
       read(arreglo1[i]);
       writeln;
    
       mayor := arreglo1[i];
       menor := arreglo1[i];
    
          for i:=1 to N-1 do
          begin
            if (arreglo1[i] > mayor) then
               mayor := arreglo1[i]
            else
               if arreglo1[i] < menor then
                 menor := arreglo1[i];
          end;
    
       writeln;
       writeln('El mayor numero es ',mayor,' en la posicion ',arreglo1[i]);
       writeln('El menor numero es ',menor,' en la posicion ',arreglo1[i]);
    readkey;
    END.
    SALUDOS!!!
      • 318
      • mensajes
      • miembro desde
      • 07/02/07
    14/08/2012
    #9 Re: Programando desde 0: 11- Subrangos y Arreglos lineales.

    Justamente, tienes que recorrer el arreglo entero luego de que le has cargado los números. Eso lo haces con un FOR. Por ejemplo, para encontrar el número mayor deberías tener una variable para guardar la posición del último número mayor que encontraste y otra para guardar dicho número. Si en tu recorrida luego encuentras un número mayor al que ya tenías, actualizas la posición y guardas el valor de ese número. Espero se entienda la idea, sino lo comento más despacio.

    Respecto a tu otra pregunta, es perfectamente válido recurrir a los temas anteriores para solucionar los actuales. Justamente los ejercicios están pensados para aplicar todo lo dado, así que si necesitas repasar, hazlo tranquilamente.

    Saludos.

      • 35
      • mensajes
      • miembro desde
      • 04/04/11
    16/08/2012
    #10 Re: Programando desde 0: 11- Subrangos y Arreglos lineales.

    Ok amigo... un poco más despacio por favor je. Lo que no comprendo es como guardo la posición del número, que tengo que utilizar sería poner a esa variable " posicion_num := arreglo1[i]" y para la otra variable que es la del número ingresado, allí es donde me confundo.
    GRACIAS.

12 Último