[ Foro de Pascal ]

Duda con Pilas

20-Dec-2010 21:48
Jesús Rodríguez
1 Respuestas

Muy buenas tardes, denuevo yo por aca con mis dudas, les pego el codigo y luego les planteo la situacion.

Clase Pila generica

unit PilaPr;
interface
  type
   Itemptr= ^Item;
   Item = object
                nombre : string;
                constructor Iniciar;
                destructor Terminado; virtual;
                procedure Imprimir; Virtual;

                 Enlace : Itemptr;
          end;
   Pila = object
                procedure Inicializar;
                procedure Meter (Elem : Itemptr);
                procedure Sacar (var ElemSup: Itemptr);
                function vacia : boolean;
                procedure LiberarPila;

                Cima: Itemptr;
          end;
implementation
   constructor Item.Iniciar;
   begin
        Enlace:= nil;
   end;

   destructor Item.Terminado;
   begin
   end;

   procedure Item.Imprimir;
   begin
   end;

   procedure Pila.Inicializar;
   begin
        Cima := nil;
   end;

   procedure Pila.Meter (Elem : Itemptr);
   begin
        Elem ^.Enlace := Cima;
        Cima := Elem;
   end;

   procedure Pila.Sacar (var ElemSup: Itemptr);
   begin
        ElemSup := Cima;
        Cima := Cima ^.Enlace;
   end;

   Function Pila.Vacia : boolean;
   begin
        Vacia := (Cima = nil);
   end;

   procedure Pila.LiberarPila;
   var
      Aux : Itemptr;
   begin
   while Cima <> nil do
   begin
        Aux := Cima;
        Cima := Cima ^.Enlace;
        dispose (Aux, Terminado);
   end;
 end;
end.


Programa de prueba implementacion de pila generica

program usodepila;

uses

   PilaPr, crt;

var

   OPila : Pila;
   Oelemento,Oelemento2,Oelemento3 : Itemptr;

begin
    Opila.Inicializar;
    new (Oelemento, Iniciar);
    Oelemento^.nombre:= 'Raton';
    new (Oelemento2, Iniciar);
    Oelemento2^.nombre:= 'Gato';
    new (Oelemento3, Iniciar);
    Oelemento3^.nombre:= 'Perro';
    Opila.Meter(Oelemento);
    writeln('Meto el primer elemento :',Oelemento^.nombre ,' y la cima es:',Opila.Cima^.nombre);
    Opila.Meter(Oelemento2);
    writeln('Meto el Segundo elemento :',Oelemento2^.nombre,' y la cima es:',Opila.Cima^.nombre);
    writeln('Y ', Opila.Cima^.nombre, ' esta detras de: ',Oelemento2^.enlace^.nombre);
    Opila.Meter(Oelemento3);
    writeln('Meto el Tercer elemento :',Oelemento3^.nombre,' y la cima es:',Opila.Cima^.nombre);
    writeln('Y ', Opila.Cima^.nombre, ' esta detras de: ',Oelemento3^.enlace^.nombre);
    writeln(Opila.Cima^.nombre,'>',Opila.Cima^.Enlace^.nombre,'>',Opila.Cima^.Enlace^.Enlace^.nombre);

    readln;
end.


Ok, Ahora la explicación :P

Navegando por la web me consegui un libro pdf de donde saque ese ejemplo de pila que estoy utilizando para experimentar y probar como funciona y ver si aprendo esto, he logrado entender su funcionamiento muy bien, pero en esto me ha nacido una duda. que se parece mucho a la duda que anteriormente tuve cuando comenze a hacer un objeto que era una matriz. alli va la duda: ¿Como hago para crear ITEMS nuevos para insertarlos en la pila? ¿Necesito un Array? Nuevamente el problema del array porque ya se que es limitado y quiero quiero que se hagan en el momento cuando los necesite, no tener que darle un limite de cuantos seran ni declararlos como variables sino que si necesito 1 item pueda decir algo como nuevo item y con eso crear el que quiera y que quede identificado claro para poder acceder a el en un futuro, ¿Como podria hacer eso?

Muchas gracias por su ayuda de antemano ;) saludos

PD. Ya se que los campos de un objeto generalmente son privados y se accede a traves de ellos por metodos los cuales si son publicos y no de la manera como lo hize directamente en el programa pero estaba apurado y queria solo probar a ver como funcionaba. xD


21-Dec-2010 20:42
Antonio P.G.

Hola Jesús. Vi ayer tu mensaje pero hoy tuve un examen y no he podido escribir hasta ahora.

Veo que te estás metiendo a fondo con esto... :P.

Te haré un comentario primero acerca del ejemplo este que has puesto aquí, del libro pdf que conseguiste, luego te diré unas recomendaciones o consejos a la hora de programar y por último (lo siento), tu pregunta. Es como me ha venido a la cabeza :).

En sí el ejemplo es correcto. Ahora bien, que sepas que todo esto se puede implementar sin objetos, ¿ok? Yo de hecho lo hice en su día (hace ya un poco de tiempo...) sin objetos, y este me ha llamado la atención, dado que está planteado desde el punto de vista de los objetos.

Bueno, algunos consejos:
- En el código, antes de implementar los métodos de los objetos, escribe alguna cabecera, como:
"(*** MÉTODOS DE ITEM ***)".

- También, en los métodos, o en general los procedimientos y funciones, describir debajo de la cabecera el cometido ayudará al futuro lector (que puedes ser tú, como a mí me pasa constantemente...) a entenderlo mejor. Ejemplo:
"funciton Pila.EsVacia : boolean;
 { Devuelve TRUE si la pila está vacía. FALSE en caso contrario. }
begin
....
....
end;"

Te aconsejo, de hecho, que lleves a cabo esta "documentación" a la hora de implementar.

- Por último, que seguro ya lo sabes, para no tener que acceder al campo del objeto, puedes crear una función que devuelva el valor del campo y ya está.

Ahora, la respuesta a tu pregunta. No te compliques con arrays. Lo único que debes hacer es usar las herramientas de tu panorama. Fíjate que tienes un método que te añade un elemento a la pila. El problema es, claro, que ese elemento es tan sólo un puntero. Pues bien, para añadir un elemento, es decir, un nombre en tu caso, crea un método que sea algo como:
"procedure Pila.AnnadirNombre (name : string);"

A este método se le proporciona un nombre (que ha sido leído previamente en el programa principal, claro). A su vez, este método crea un item de los dinámicos, le asigna el nombre, y lo mete en la pila. ¿Cómo lo mete en la pila? Mediante el uso del otro método que ya tienes, el de "Meter". Y entonces termina el método "AnnadirNombre". ¿Entendido? Si no ha quedado claro, dímelo.

Por último te propondré un par de cosas. La primera es que crees un método-procedimiento para la Pila que se llame, por ejemplo, "MirarCima". Este procedimiento devolverá (por variable) el nombre del elemento que se encuentra en la cima.

La segunda, es que crees un programa de tipo "menú para probar" (así los llamo yo). Se trata de un programa que te muestra un menú sencillito (todo con "writeln's") y tras el cual tú seleccionas una opción, y el programa realiza la operación correspondiente a esa opción. Para que se repita el menú, se usa un bucle repeat ... until (porque al menos lo ejecutas una vez) y al until se le pone la condición de que "has seleccionado la opción de Salir". Así, además puedes introducir varios nombres, usando varias veces la misma opción.

Creo que eso es todo lo que tengo que decirte acerca de esto. Bueno, me guardo alguna cosa, como lo de medir la longitud de una pila, pero eso si acaso tras haber conseguido el resto.

Yo también fui por pasos. Como un computador :P.

¡Ciao!






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)