BotonMenu
BotonIndice

Visita : http://www.conoce3000.com
Paypal : https://www.paypal.me/conoce3000/1

PASCAL CON FREE PASCAL

PASCAL CON FREE PASCAL

PASCAL CON FREE PASCAL


14. LISTA DE CADENAS TSTRINGLIST.
14.7. GENERALIZACIÓN CON TSTRINGLIST.
14. LISTA DE CADENAS TSTRINGLIST.
14.7. GENERALIZACIÓN CON TSTRINGLIST.
14. LISTA DE CADENAS TSTRINGLIST.
14.7. GENERALIZACIÓN CON TSTRINGLIST.

SIGUIENTE

SIGUIENTE

SIGUIENTE


‒ Generalización con TstringList.

En este capítulo se explicará como ampliar la clase TStringList acorde a nuestras necesidades, lo que haremos es una generalización de TSTringList, es decir crearemos una nueva clase TStringList heredando los métodos, atributos y propiedades ya existentes para crear el nuestro propio.

Esta nueva clase permitirá 2 cosas, primero ordenar la lista de cadenas de caracteres en orden ascendente y descendente, dependiendo del valor que tendrá el atributo orden, si es verdadero o true entonces la lista se ordena en orden ascendente y si es falso o false se ordena en orden descendente.

Lo segundo que permitirá hacer esta nueva clase es permitir colocar las cadenas de caracteres tanto en orden ascendente o descendente, usando el atributo Sorted. Pero para ello se debe cambiar el método Find de la clase TStringList, esto lo haremos usando polimorfismo por sobre-escritura con enlace posterior. Para efectos de hacerlo simple el nombre de la clase se llamará TMyStringList.

Para lo primero debemos cambiar el método Sort que también se sobre escribirá, ya que Sort es un método virtual (polimorfismo por sobre-escritura). La nueva clase sería como la siguiente:

TMyStringList=class(TStringList)
    public
    Orden:boolean; //true ascendente, false descendente
    Constructor Create;
    procedure Sort;override;
End;

y la implementación de los métodos sería la siguiente:

Function Comparar(i,j:ansistring):integer;

Begin

  if i=j then Comparar:=0

  else if i>j then Comparar:=1

  else Comparar:=-1

End;

 

Constructor TMyStringList.create;

Begin

  inherited Create;

  Orden:=true; //ascendente

End;

 

Procedure TMyStringList.Sort;

Begin

  if orden then CustomSort(@Ascendente)

  else CustomSort(@Descendente);

End;

Tal como se puede observar también se esta reemplazando el constructor Create por el nuestro, para poder inicializar el atributo orden a true, que será la opción por defecto, es decir método Sort ordenará la lista en orden ascendente.

El método Sort hace uso de CustomSort que se explico en el capítulo anterior para ordenar la lista, pero siempre comprobando el atributo orden, para saber en que orden debe ordenarse la lista.

Obviamente las funciones Ascendente y Descendente son funciones que no pertenecen a la clase, es decir debemos escribirlas aparte, con lo que la unidad quedaría del siguiente modo:


Descargar
{$codepage utf8}
{$mode objfpc}

Unit MyStringList01;
Interface
Uses sysutils, classes;

function Comparar(i,j:ansistring):integer;
function Descendente(List: TStringList; Index1, Index2: Integer): Integer;
function Ascendente(List: TStringList; Index1, Index2: Integer): Integer;

Type
  TMyStringList=class(TStringList)
  public
    Orden:boolean; //true ascendente, false descendente
    Constructor create;
    Function Find(const S: ansistring; out Index: integer): Boolean; override;
    procedure sort;override;
  End;

Implementation

function Comparar(i,j:ansistring):integer;
  Begin
    if i=j then Comparar:=0
    else if i>j then Comparar:=1
    else Comparar:=-1
  End;

function Descendente(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := Comparar(List[Index2], List[Index1]);
end;

function Ascendente(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := Comparar(List[Index1], List[Index2]);
end;

Constructor TMyStringList.create;
Begin
  inherited Create;
  Orden:=true; //ascendente
End;

procedure TMyStringList.sort;
 Begin
  if orden then
    CustomSort(@Ascendente)
  else
    CustomSort(@Descendente);
 End;

End.
Código fuente 33: Primera versión de TMyStringList.
Descargar

Para el segundo caso debemos cambiar el método Find por el nuestro propio, el método Find original usa una búsqueda binaria. La búsqueda binaria se explica en el capitulo 08-06. El método Find devuelve verdadero si lo encontró y falso en caso no haya encontrado lo que estaba buscando, pero además devuelve en el parámetro index, la posición en donde se encontró el elemento buscado, en caso no se haya encontrado el valor buscado este debe devolver la posición en donde se puede insertar el nuevo elemento en la lista de acuerdo a como este ordenado la lista, en orden ascendente o descendente. La unidad entonces sería la siguiente:


Descargar
{$codepage utf8}
{$mode objfpc}

Unit MyStringList02;
Interface
Uses sysutils, classes;

function Comparar(i,j:ansistring):integer;
function Descendente(List: TStringList; Index1, Index2: Integer): Integer;
function Ascendente(List: TStringList; Index1, Index2: Integer): Integer;

Type
  TMyStringList=class(TStringList)
  public
    Orden:boolean; //true ascendente, false descendente
    Constructor create;
    Function Find(const S: ansistring; out Index: integer): Boolean; override;
    procedure sort;override;
  End;

Implementation

function Comparar(i,j:ansistring):integer;
  Begin
    if i=j then Comparar:=0
    else if i>j then Comparar:=1
    else Comparar:=-1
  End;

function Descendente(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := Comparar(List[Index2], List[Index1]);
end;

function Ascendente(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := Comparar(List[Index1], List[Index2]);
end;

Constructor TMyStringList.create;
Begin
  inherited Create;
  Orden:=true; //ascendente
End;

procedure TMyStringList.sort;
 Begin
  if orden then
    CustomSort(@Ascendente)
  else
    CustomSort(@Descendente);
 End;

Function TMyStringList.Find(const S: ansistring; Out Index: Integer): Boolean;
 var
  primero,ultimo,mitad:integer;
  CompareRes: integer;
  encontro:boolean;
begin

  primero := 0;
  ultimo := Count - 1;  
  encontro:=false;

  While (ultimo>=primero) and not(encontro)  do
    Begin
       mitad:=(primero+ultimo) div 2;
       //Segun orden se hace la comparación
       if orden
         then CompareRes:=Comparar(Strings[mitad],S)
         else CompareRes:=Comparar(S,Strings[mitad]);

       if CompareRes=0 then encontro:=true
       else
       if CompareRes>0
         then ultimo:=mitad-1
         else primero:=mitad+1;
    End;
  if encontro then index:=mitad
  else index:=primero;
  result:=encontro;

end;

end.
Código fuente 34: Versión final de TMyStringList.
Descargar

El método Find también hará uso de la función Comparar para comprobar y determinar en que parte de la lista realizar la búsqueda, es decir en la parte superior o inferior. Además según la variable orden, se determinará la comparación entre el elemento a buscar y el elemento que se encuentre en el medio o mitad de la lista.

En caso la búsqueda tuvo éxito entonces la posición en donde se encontró el elemento estará en la variable mitad, en caso contrario la variable primero tendrá el valor en donde se puede insertar el elemento no encontrado en la lista.

El siguiente programa es un ejemplo de su funcionamiento.


Descargar
{$codepage utf8}
{$mode objfpc}

Uses sysutils, classes, MyStringList02
{$ifdef Linux},cwstring{$endif};

Var ListaCadenas:TMyStringList;
Begin
  Writeln('== Ascendente ==');
  ListaCadenas:=TMyStringList.create;
  ListaCadenas.Add('Olgado');
  ListaCadenas.Add('Carro');
  ListaCadenas.Add('Arriba');
  ListaCadenas.Orden:=true;
  ListaCadenas.Sort;
  ListaCadenas.Sorted:=true;
  ListaCadenas.Duplicates:=dupAccept;
  ListaCadenas.Add('Alegria');
  ListaCadenas.Add('Zorro');
  ListaCadenas.Add('Zarten');
  ListaCadenas.Add('Colorado');
  ListaCadenas.Add('Colorado');
  ListaCadenas.Add('Colorado');
  ListaCadenas.Add('Colorado');
  ListaCadenas.Add('Daniel');
  Writeln(ListaCadenas.Text);

  Writeln('== Descendente ==');
  ListaCadenas:=TMyStringList.create;
  ListaCadenas.Add('Olgado');
  ListaCadenas.Add('Carro');
  ListaCadenas.Add('Arriba');
  ListaCadenas.Orden:=false;
  ListaCadenas.Sort;
  ListaCadenas.Sorted:=true;
  ListaCadenas.Duplicates:=dupAccept;
  ListaCadenas.Add('Alegria');
  ListaCadenas.Add('Zorro');
  ListaCadenas.Add('Zarten');
  ListaCadenas.Add('Colorado');
  ListaCadenas.Add('Colorado');
  ListaCadenas.Add('Colorado');
  ListaCadenas.Add('Colorado');
  ListaCadenas.Add('Daniel');
  Writeln(ListaCadenas.Text);
End.
Código fuente 35: Ejemplo del uso de TMyStringList.
Descargar




SIGUIENTE
SIGUIENTE
SIGUIENTE



 
‒ Comentarios y sugerencias.

Agradezco de antemano, todo comentario, sugerencia, y donativo (a través de Paypal me), que ayude a mejorar los contenidos educativos de Conoce 3000. Además, cualquier pregunta o duda que tengas lo puedes hacer por este medio. Pero, todo contenido que pueda resultar ofensivo, malicioso, racista, sexista, discriminatorio, obsceno, vulgar será eliminado.


Comments System WIDGET PACK






PORTADA |  INTERESANTE |  APUNTES |  LIBROS |  GALERIA


Creative Commons License


Todos los textos, imágenes y videos de Conoce3000 estan colocados bajo una licencia : Creative Commons Reconocimiento-NoComercial 3.0 Unported License.