Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 10-02-2015
martin.lazzeri martin.lazzeri is offline
Registrado
NULL
 
Registrado: ago 2014
Posts: 2
Poder: 0
martin.lazzeri Va por buen camino
Reusar unidad en Delphi

Hola Gente!

Estoy desarrollando un proyecto para una materia, tenemos que usar diferentes estructuras de datos, como por ejemplo arboles, listas simples y doblemente enlazadas.

Por ejemplo aca les dejo la libreria de arbol:

Código Delphi [-]
unit Arbol;

interface

const
      posNula = -1;
      valorNulo = 0;
      claveNula = 'AAAAAA';
      ruta = 'C:\Users\Martin\Desktop\prog2\Veterinaria\Arbol\';

type

      TipoPosicion = integer;
      tipoclave = string[6];

      RegistroDatosArbol = record
                                  Clave : TipoClave;
                                  Padre : TipoPosicion;
                                  HijoDerecho : TipoPosicion;
                                  HijoIzquierdo : TipoPosicion;
                           end;

      TipoArchivoDatos = file of RegistroDatosArbol;

      RegistroControlArbol = record
                                    Raiz : TipoPosicion;
                                    Cantidad : integer;
                                    Borrado : TipoPosicion;
                             end;
      TipoArchivoControl = file of RegistroControlArbol;

      TipoArbol = record
                           D : TipoArchivoDatos;
                           C : TipoArchivoControl;
                  end;
var
      Me : TipoArbol;

// Operaciones de la libreria
Procedure CrearArbol(var Me : TipoArbol; archivoDatos : string; archivoControl : string );
Procedure AbrirArbol (var Me : TipoArbol);
Procedure CerrarArbol (var Me : TipoArbol);
Function Raiz(var Me : TipoArbol) : TipoPosicion;
Function Padre(var Me: TipoArbol; pos : TipoPosicion) : TipoPosicion;
Procedure CapturarNodo(var Me : TipoArbol; pos : TipoPosicion; var regDatos : RegistroDatosArbol);
Procedure ModificarNodo(var Me : TipoArbol; pos : TipoPosicion; regDatos : RegistroDatosArbol);
Procedure InsertarNodo(var Me: TipoArbol; pos : TipoPosicion; regDatos : RegistroDatosArbol);
Function Buscar(var Me: TipoArbol; clave: TipoClave; var pos: TipoPosicion) : boolean;

implementation

Procedure CrearArbol(var Me : TipoArbol; archivoDatos : string; archivoControl : string );
var
    registroControlAux : RegistroControlArbol;
begin
      {$I-}
      assign(Me.D, ruta + archivoDatos);
      assign(Me.C, ruta + archivoControl);

      // Abro el archivo de datos para solo lectura
      reset (Me.D);

      // Verifico que no haya errores
      if(IORESULT <> 0)
        then
            rewrite (Me.D); // Creo el archivo, ya que no existía y se abre para escritura

      //Abro el archivo de control para solo lectura
      reset (Me.C);

      //Verifico que no haya errores
      if(IORESULT <> 0)
        then
            begin
                  rewrite (Me.C); //Creo el archivo, ya que no existía y se abre para escritura

                  //A continuación inicializo los campos del registro
                  registroControlAux.Raiz := posNula;
                  registroControlAux.Cantidad := 0;
                  registroControlAux.Borrado := posNula;
                  write (Me.C, registroControlAux); //Escribo la información en el archivo
            end;
      //A continuación cierro los dos archivos
      close (Me.D);
      close (Me.C);
      {$I+}
end;

Procedure AbrirArbol (var Me : TipoArbol);
begin
      reset (Me.D);
      reset (Me.C);
end;

Procedure CerrarArbol (var Me : TipoArbol);
begin
      close (Me.D);
      close (Me.C);
end;

Function Raiz(var Me : TipoArbol) : TipoPosicion;
var
    registroControlAux : RegistroControlArbol;
begin
      seek(Me.C, valorNulo);
      read(Me.C, registroControlAux);
      Raiz := registroControlAux.Raiz;
end;

Function Padre(var Me : TipoArbol; pos : TipoPosicion) : TipoPosicion;
var
    registroDatosAux : RegistroDatosArbol;
begin
      seek(Me.D, pos);
      read(Me.D, registroDatosAux);
      Padre := registroDatosAux.Padre;
end;

Procedure CapturarNodo(var Me : TipoArbol; pos : TipoPosicion; var regDatos : RegistroDatosArbol);
begin
      seek(Me.D, pos);
      read(Me.D, regDatos);
end;

Procedure ModificarNodo(var Me : TipoArbol; pos : TipoPosicion; regDatos : RegistroDatosArbol);
var
    registroDatosAux : RegistroDatosArbol;
begin
      seek(Me.D, pos);
      read(Me.D, registroDatosAux);

      registroDatosAux.Padre := regDatos.Padre;
      registroDatosAux.HijoDerecho := regDatos.HijoDerecho;
      registroDatosAux.HijoIzquierdo := regDatos.HijoIzquierdo;
      registroDatosAux.Clave := regDatos.Clave;

      seek(Me.D, pos);
      write(Me.D, registroDatosAux);
end;

Procedure InsertarNodo(var Me: TipoArbol; pos : TipoPosicion; regDatos : RegistroDatosArbol);
var
    registroControlAux: RegistroControlArbol;
    posNueva: TipoPosicion;
    registroDatosAux, padre: RegistroDatosArbol;
begin
      Seek(Me.C, valorNulo);
      Read(Me.C, registroControlAux);

    if (registroControlAux.Borrado = posNula)
      then
          posNueva := FileSize(Me.D)
      else
          begin
                posNueva := registroControlAux.Borrado; //Tengo uno borrado, entonces lo recupero
                Seek(Me.D, posNueva);
                Read(Me.D, registroDatosAux);
                registroControlAux.Borrado := registroDatosAux.HijoDerecho //Para que pongamos siempre ese
          end;

    if (registroControlAux.Raiz = posNula) then //Significa que esta vacio
      begin
            registroControlAux.Raiz := posNueva;
            regDatos.Padre := posNula;    //
            regDatos.HijoIzquierdo := posNula;  // Para darle los nuevos enlaces que sino vienen con basura
            regDatos.HijoDerecho := posNula;  //
            registroControlAux.Cantidad := registroControlAux.Cantidad + 1;
      end
    else
         begin
              Seek(Me.D, pos);
              Read(Me.D, padre);
              if (regDatos.Clave <= padre.Clave)
                then //Para engancharlo
                    padre.HijoIzquierdo := posNueva
                else
                    Padre.HijoDerecho := posNueva;

              regDatos.HijoIzquierdo := posNula;
              regDatos.HijoDerecho := posNula;
              regDatos.Padre := pos;

              Seek(Me.D, pos);
              Write(Me.D, padre);
              registroControlAux.Cantidad := registroControlAux.Cantidad + 1;
          end;

    Seek(Me.C, 0);
    Write(Me.C, registroControlAux);
    Seek(Me.D, posNueva);
    Write(Me.D, regDatos);
end;


{Procedure InsertarNodo(var Me: TipoArbol; pos : TipoPosicion; regDatos : RegistroDatosArbol);
var
    registroControlAux : RegistroControlArbol;
    registroDatosAux : RegistroDatosArbol;
    posNueva : TipoPosicion;

begin
      seek(Me.C, valorNulo);
      read(Me.C, registroControlAux);

      if(registroControlAux.Borrado = posNula)
        then
            posNueva := filesize(Me.D)
        else
            begin
                  posNueva := registroControlAux.Borrado;
                  seek(Me.D, posNueva);
                  read(Me.D, registroDatosAux);
                  registroControlAux.Borrado := registroDatosAux.Padre;
            end;


      if(registroControlAux.Raiz = posNula)
        then // Inserto en árbol vacío
            begin
                  registroControlAux.Raiz := posNueva;
                  regDatos.HijoIzquierdo := posNula;
                  regDatos.HijoDerecho := posNula;
                  regDatos.Clave := claveNula;
            end
        else
            begin
                  seek(Me.D, pos);
                  read(Me.D, registroDatosAux);
                  if(regDatos.Clave <= registroDatosAux.Clave)
                    then
                        registroDatosAux.HijoIzquierdo := posNueva
                    else
                        registroDatosAux.HijoDerecho := posNueva;

                  regDatos.Padre := pos;
                  regDatos.HijoDerecho := posNula;
                  regDatos.HijoIzquierdo := posNula;
            end;

        seek(Me.D, pos);
        write(Me.D, registroDatosAux);

        registroControlAux.Cantidad := registroControlAux.Cantidad + 1;

        //Actualizo el archivo de control

        seek(Me.C, valorNulo);
        write(Me.C, registroControlAux);

        //Actualizo el archivo de datos

        seek(Me.D, posNueva);
        write(Me.D, regDatos);
end;    }

Function ArbolVacio(var Me: TipoArbol) : boolean;
var
    registroControlAux: RegistroControlArbol;
begin
      Seek(Me.C, valorNulo);
      Read(Me.C, registroControlAux);
      ArbolVacio := (registroControlAux.Raiz = posNula);
end;

Function HijoIzquierdo(var Me: TipoArbol; pos: TipoPosicion) : TipoPosicion;
var
    registroDatosAux: RegistroDatosArbol;
begin
      Seek(Me.D, pos);
      Read(Me.D, registroDatosAux);
      HijoIzquierdo := registroDatosAux.HijoIzquierdo;
end;

Function HijoDerecho(var Me: TipoArbol; pos: TipoPosicion) : TipoPosicion;
var
    registroDatosAux: RegistroDatosArbol;
begin
      Seek(Me.D, pos);
      Read(Me.D, registroDatosAux);
      HijoDerecho := registroDatosAux.HijoDerecho;
end;

Function Buscar(var Me: TipoArbol; clave: TipoClave; var pos: TipoPosicion) : boolean;
var
    registroControlAux : RegistroControlArbol;
    registroDatosAux :  RegistroDatosArbol;
    posicionPadre: TipoPosicion;
    encontre: boolean;
begin
      Seek(Me.C, valorNulo);
      Read(Me.C, registroControlAux);
      pos:= posNula;
      posicionPadre:= posNula;
      encontre := false;

      while( not(encontre) and (pos <> -1)) do
      begin
            Seek(Me.D, pos);
            Read(Me.D, registroDatosAux);
            if (clave = registroDatosAux.Clave)
              then
                    encontre := true
              else
                    begin
                          posicionPadre:= pos;
                          if (clave < registroDatosAux.Clave)
                            then
                                  pos := registroDatosAux.HijoIzquierdo
                            else
                                  pos:= registroDatosAux.HijoDerecho
                    end;
      end;

      //Para saber donde deberia estar
      if (not (encontre))
        then
            pos:= posicionPadre;

      Buscar := encontre;
end;

end.

Esta libreria, por ejemplo deberia usarla desde otra unidad donde modelo un ingreso de mascotas al sistema. El sistema modela una veterinaria.

El tema es que mi TipoDatoMascota es un registro con datos propios (nombre mascota, peso, edad, etc) y tengo que vincularlo de alguna forma con el registro de datos del arbol. Lo hice agregano una propiedad a ese registro de tipo RegistroDatoArbol, hasta ahi todo bien, el tema es que cuando quiero insertar un nuevo nodo con la libreria de arbol, lo inserta, pero no estoy pudiendo traer los datos propios de la mascota. Como la idea es reusar la libreria, creo que no es una buena opcion declarar los tipos propios de la mascota dentro del registro TipoDatosArbol, ya que esta misma libreria deberia usarla con otras unidades con otros datos totalmente distinto.

¿Alguien sabe como puedo modelar esta especie de genericidad?

Muchas gracias.
Responder Con Cita
  #2  
Antiguo 10-02-2015
engranaje engranaje is offline
Miembro
 
Registrado: may 2011
Posts: 163
Poder: 14
engranaje Va por buen camino
Parece puramente académico. ¿No se puede utilizar clases?. Lo pregunto porque si efectivamente como parece es un ejercicio y debe utilizarse los conocimientos adquiridos hasta el momento, bien es posible que aún no sepais nada de los objetos y debais "apañaros" con lo que sabeis. Igual no te sirve una solución que pase por declarar varias clases y utilizar herencia y polimorfismo para solucionar el problema aunque esa sea la mejor opción.
Responder Con Cita
  #3  
Antiguo 10-02-2015
martin.lazzeri martin.lazzeri is offline
Registrado
NULL
 
Registrado: ago 2014
Posts: 2
Poder: 0
martin.lazzeri Va por buen camino
Lamentablemente no se pueden utilizar clases y nada orientado a objetos, es ahí que tengo el problema.
Responder Con Cita
  #4  
Antiguo 10-02-2015
Avatar de Neftali [Germán.Estévez]
Neftali [Germán.Estévez] Neftali [Germán.Estévez] is offline
[becario]
 
Registrado: jul 2004
Ubicación: Barcelona - España
Posts: 18.286
Poder: 10
Neftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en brutoNeftali [Germán.Estévez] Es un diamante en bruto
Cita:
Empezado por martin.lazzeri Ver Mensaje
Lamentablemente no se pueden utilizar clases y nada orientado a objetos, es ahí que tengo el problema.


Justamente la solución es utilizar herencia.
Definir esos "elementos" que varían como clases y no como elementos fijos.

Revisa Genéricos, pero va a ser lo mismo...
__________________
Germán Estévez => Web/Blog
Guía de estilo, Guía alternativa
Utiliza TAG's en tus mensajes.
Contactar con el Clubdelphi

P.D: Más tiempo dedicado a la pregunta=Mejores respuestas.
Responder Con Cita
  #5  
Antiguo 10-02-2015
Avatar de duilioisola
[duilioisola] duilioisola is offline
Miembro Premium
 
Registrado: ago 2007
Ubicación: Barcelona, España
Posts: 1.734
Poder: 20
duilioisola Es un diamante en brutoduilioisola Es un diamante en brutoduilioisola Es un diamante en bruto
Se me ocurre utilizar punteros, pero eso complica un poco las cosas...
Hablo de memoria, pero sería algo así:
Código Delphi [-]
type
// Tipos de datos
TElemento = record
   id: integer
   tipo: string;
   dato: pointer;
end;

TAnimal = record
  nombre: string;
  peso: integer;
  edad: integer;
end

TPlanta = record
  especie: strnig
  aguanecesaria: integer;
end

// Punteros a tipos de datos
var
  PElemento: ^TElemento;
  PAnimal: ^TAnimal;
  PPlanta: ^TPlanta;
 
begin
  // Creo un elemento
  UnElemento := New(PElemento);
  UnElemento.id := 1;
  UnElemento.tipo := 'ANIMAL';
  // Creo un dato de tipo animal
  UnElemento.dato := New(PAnimal);
  PAnimal(UnElemento.dato)^.nombre := 'CHUCHO';
  ...
  // Creo otro elemento
  UnElemento := New(PElemento);
  UnElemento.id := 2;
  UnElemento.tipo := 'PLANTA';
  // Creo un dato de tipo planta
  UnElemento.dato := New(PPlanta);
  PPlanta(UnElemento.dato)^.especie := 'GRIASOL';
  ...
  // Libero memoria
  Dispose(UnElemento.dato);
  Dispose(UnElemento);
end;
Responder Con Cita
  #6  
Antiguo 13-02-2015
engranaje engranaje is offline
Miembro
 
Registrado: may 2011
Posts: 163
Poder: 14
engranaje Va por buen camino
Yo si he de ser sincero, tras leer tu descripción del problema y en base a lo que he entendido harías lo siguente para este caso en concreto y dando por sentado que para un caso genérico lo mejor sería crear los objetos necesarios y usar herencia.

Basandonos en tu tipo
Código Delphi [-]
type      
  RegistroDatosArbol = record                                   
    Clave : TipoClave;                                   
    Padre : TipoPosicion;                                   
    HijoDerecho : TipoPosicion;                                  
    HijoIzquierdo : TipoPosicion;                            
  end;

y en que tu
Cita:
TipoDatoMascota es un registro con datos propios (nombre mascota, peso, edad, etc)
Lo mejor sería que añadieras tu tipo TipoDatoMascota clave,padre,hijoDerecho e hijo izquierdo tal y como los tiene RegistroDatosArbol.

Despues deberias asegurarte de que tu TipoDatoMascota está definida en unit de tipos que pudieras añadir al uses de las units en la que vayas a usar y añadiria esa unit al uses de la unit Arbol.

Finalmente eliminina la declaración de RegistroDatosArbol de la unit Arbol y sustituye los sitios en los que se utiliza por TipoDatoMascota .

Deberias llamar a tu árbol "árbol de mascotas" ya que solo servirá para organizar records del tipo TipoDatoMascota pero deberas creo leyendo tu descripción del problema no necestias nada más porque en principio tu árbol solo va a ser usado para trabajar con tipoDatoMascota. Sospecho que posteriormente quien te esté enseñanado añadira la necesidad de poder utilizar el arbol (y los otros tipos de estrucutras de datos) para poder utilizar disintos tipos y no siempre el mismo y en ese punto comenzará a explicar los punteros o la orientación a objetos.

Creo que normalmente cuando alquien eseña a programar primero da pocas herramientas y despues pide que se ejerciten esas herramientas problemas que pueder solucionarse utilizandolas. Posteriormente se añaden complejidades que no pueden solucionarse con las herramientas que se conocen y se enseña una nueva herramienta para solucionar el problema. La orientación a objetos es la herramienta óptima para crear un árbol genérico. Los punteros y los tipos genéricos son herramientas que pueden utilizarse para conseguirlo si no se permite utilizar objetos. Pero siempre hay que aprender primero lo básico.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Unidad CRT para Delphi Lord Delfos Varios 7 26-09-2008 18:18:00
Reusar consulta Gaim2205 SQL 3 08-01-2008 21:06:49
reusar un mismo form enecumene OOP 7 18-08-2007 01:44:48
Como BORRAR una unidad de RED en Delphi???? AGAG4 Redes 1 28-04-2007 19:08:58
Unidad ZLib de Delphi: Necesita DLL? Pandre Varios 2 04-04-2005 17:34:07


La franja horaria es GMT +2. Ahora son las 00:23:47.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi