Ir al contenido


Foto

Rutinas pequeñas que pueden ayudar


  • Por favor identifícate para responder
27 respuestas en este tema

#21 Al González

Al González

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 99 mensajes

Escrito 09 febrero 2009 - 11:49

¡Hola!

Antes que nada un saludo a todos, hace días que no venía por aquí.  :$

Aprovecho para saludar especialmente a Cadetill, de quien tengo muy gratos recuerdos de otro lugar y época. Cómo los he echado de menos a ti y a el resto de la pandilla de aquellos viejos tiempos.  Los relaciono mucho con mi feliz estancia en Cuernavaca del 2004 a pesar de estar a miles de jornadas de mula.  Aquellas noches de descubrimiento de Firebird, romance y filosofía eran increíbles. :)

Bueno, aquí mi aportación:



delphi
  1.   Function Uno (Const Valor :Boolean) :Integer;
  2.   Begin
  3.     Result := (Byte (Valor) * 2) - 1;
  4.   End;



Esta función convierte un valor Boolean, False o True, en un entero de valor -1 o +1, respectivamente.

¿Utilidad?  Podría ser el transferir una bandera que indica ir hacia adelante —True— o hacia atrás —False— en el valor entero (+1 o -1) que habría que sumar a una propiedad para realizar la acción en el sentido indicado.

Internamente False es 0 y True 1.  Lo que hace esta función es darle simetría aritmética a esos valores lógicos.  De otra forma, si sólo intentáramos un clásico molde de tipo como "Byte (Valor)", con False sumaríamos 0 (no se movería para ningún lado) y sólo con True se movería.

Sucede que a veces una rutina recibe un parámetro Boolean llamado, por ejemplo, "GoForward", para indicar si queremos que avance o retroceda (True o False).  Dentro de la función, si ese avance o retroceso implica un incremento o decremento de igual magnitud pero de signo contrario a un contador, propiedad de posición, etc., dicha función puede llamar a Uno para obtener el incremento en sí o el factor por el cual haya que multiplicar el incremento.



delphi
  1. Position := Position + Uno (GoForward);



Perdón si fue mucho rollo. (~) :D

Uno (abrazo);

Al González. :)
  • 0

#22 Héctor Randolph

Héctor Randolph

    501st Legion

  • Administrador
  • 664 mensajes
  • LocationMéxico

Escrito 10 febrero 2009 - 10:27

Seguramente te ha sucedido que al realizar una búsqueda por internet, el motor de búsqueda te muestra algunas sugerencias con palabras "muy similares" a la que has escrito.

Por ejemplo, si escribes "Delfi" o "Delpi" probablemente el motor de búsqueda responderá:

"Quizás quiso decir Delphi"  8-|

Pero, ¿cómo logra el motor determinar cuales palabras se parecen entre sí?. La respuesta puede ser muy compleja, sin embargo, la pieza principal en este tipo de algoritmos es encontrar una función que me diga qué tan lejos se encuentra una palabra de otra.

Alguna vez un matemático ruso llamado Vladimir Levenshtein propuso una función muy simple para determinar la distancia que existe entre un par de palabras.

Se le llama Distancia de Levenshtein o distancia de edición al número mínimo de operaciones requeridas para transformar una cadena de caracteres en otra.

Es útil en programas que determinan cuán similares son dos cadenas de caracteres, como es el caso de los correctores de ortografía.

Por ejemplo, la distancia de Levenshtein entre "kitten" y "sitting" es de 3 porque se necesitan al menos tres ediciones elementales para cambiar uno en el otro.

1. kitten ? sitten (sustitución de 'k' por 's')
2. sitten ? sittin (sustitución de 'e' por 'i')
3. sittin ? sitting (inserción de 'g' al final)


Bueno dejo aquí la implementación en Delphi del algoritmo de Levenshtein.



delphi
  1. function DistanciaLevenshtein(Str1, Str2: String): Integer;
  2. var
  3.   d : array of array of Integer;
  4.   Len1, Len2 : Integer;
  5.   i, j, cost: Integer;
  6. begin
  7.   Len1:=Length(Str1);
  8.   Len2:=Length(Str2);
  9.   SetLength(d,Len1+1);
  10.   for i := Low(d) to High(d) do
  11.     SetLength(d[i],Len2+1);
  12.  
  13.   for i := 0 to Len1 do
  14.     d[i,0]:=i;
  15.  
  16.   for j := 0 to Len2 do
  17.     d[0,j]:=j;
  18.  
  19.   for i:= 1 to Len1 do
  20.     for j:= 1 to Len2 do
  21.     begin
  22.       if Str1[i]=Str2[j] then
  23.         cost:=0
  24.       else
  25.         cost:=1;
  26.       d[i,j]:= Min(d[i-1, j] + 1,    // costo de borrar,
  27.                   Min(d[i, j-1] + 1, // costo de insertar
  28.                       d[i-1, j-1] + cost));  // costo de sustituir                           
  29.     end;
  30.   Result:=d[Len1,Len2];
  31. end;




Ejemplo de uso:



delphi
  1.   ShowMessageFmt('La distancia entre kitten y sitting es : %d',[DistanciaLevenshtein('kitten','sitting')]);



Esta función por si misma resuelve el problema de determinar qué tan parecidas son las palabras entre sí, sin embargo, existe una limitante que se origina por el número de operaciones que se deben realizar y aún utilizando una poderosa computadora, aplicar la función sobre un enorme conjunto de datos no es eficiente. Por lo tanto, para utilizar esta función en la práctica, debemos idear un buen algoritmo que minimice el número de comparaciones entre palabras.

Saludos
  • 0

#23 poliburro

poliburro

    Advanced Member

  • Administrador
  • 4.945 mensajes
  • LocationMéxico

Escrito 10 febrero 2009 - 10:51

Interesante algoritmo amigo hector muchas gracias por la aportación
  • 0

#24 seoane

seoane

    Advanced Member

  • Administrador
  • 1.257 mensajes
  • LocationEspaña

Escrito 15 febrero 2009 - 12:11

Comprobar si una dirección ip es valida.



delphi
  1. uses WinSock;
  2.  
  3. function IPValida(IP: String): Boolean;
  4. begin
  5.   Result:= inet_addr(PChar(IP)) <> INADDR_NONE;
  6. end;
  7.  
  8. // Por ejemplo
  9. SHowMessage(BoolToStr(IPValida('256.168.1.1'),TRUE));


  • 0

#25 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.962 mensajes
  • LocationMadrid - España

Escrito 24 febrero 2009 - 10:13

Esta rutina la he posteado en C/C++, pero por los comentarios, la reescribo aquí­.

Se trata de averiguar las fechas de semana santa, tan "imprevisibles" a la hora de realizar los calendarios laborales.



delphi
  1. function GetPascua(year: Integer):TDate;
  2. var
  3.   a, b, c, AA, BB : Integer;
  4. begin
  5.   // Limites de la Semana Santa 22 de marzo hasta 25 de abril
  6.   // Solo desde 1900 hasta el año 2100 las cifras 24 y 5 son cte y válidas
  7.   a := year mod 19;
  8.   b := year mod 4;
  9.   c := year mod 7;
  10.   AA := (19*a + 24) mod 30;
  11.   BB := (2*+ 4*c + 6*AA + 5) mod 7;
  12.  
  13.   Result := EncodeDate(year, 3, 1) + AA + BB + 22 -1;
  14. end;



Este es el Domingo de Pascua. El jueves Santo será, Pascua-3 y el Viernes Santo, Pascua-2.

Saludos.

  • 0

#26 seoane

seoane

    Advanced Member

  • Administrador
  • 1.257 mensajes
  • LocationEspaña

Escrito 09 abril 2009 - 05:54

Obtener los archivos de un directorio ordenados por fecha de modificación:


delphi
  1. function Comparar(List: TStringList; Index1, Index2: Integer): Integer;
  2. begin
  3.   Result:= Integer(List.Objects[Index1]) - Integer(List.Objects[Index2]);
  4. end;
  5.  
  6. procedure Buscar(Path,Mask: string; Attr: Integer; Lista: TStringList);
  7. var
  8.   SearchRec: TSearchRec;
  9. begin
  10.   if Copy(Path,Length(Path),1) <> '\' then
  11.     Path:= Path + '\';
  12.   if FindFirst(Path + Mask,Attr,SearchRec) = 0 then
  13.   repeat
  14.     Lista.AddObject(Path + SearchRec.Name, TObject(SearchRec.Time));
  15.   until FindNext(SearchRec) <> 0;
  16.   FindClose(SearchRec);
  17.   Lista.CustomSort(Comparar);
  18. end;



Por ejemplo:


delphi
  1. var
  2.   Lista: TStringList;
  3. begin
  4.   Lista:= TStringList.Create;
  5.   try
  6.     Buscar('C:\Directorio','*.*',faAnyFile,Lista);
  7.     Memo1.Lines.Assign(Lista);
  8.   finally
  9.     Lista.Free;
  10.   end;
  11. end;


  • 0

#27 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.177 mensajes
  • LocationMéxico

Escrito 09 abril 2009 - 08:32

Como siempre amigo seoane, pones código que me va a servir y en el momento justo (y)

Salud OS
  • 0

#28 Caral

Caral

    Advanced Member

  • Administrador
  • 4.261 mensajes
  • LocationCosta Rica

Escrito 09 abril 2009 - 08:47

Hola

Como siempre amigo seoane, pones código que me va a servir y en el momento justo (y)

Salud OS

A mi en el momento en el que lo entienda seguro me servirá. :D
Los codigos de seoane solo los copio y los pego, algun dia, digo yo, los entendere. (y) :D
Saludos
  • 0