Autor Tema: Rutinas pequeñas que pueden ayudar  (Leído 2373 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Al González

  • Miembro Platino
  • *****
  • Gracias
  • -Dados: 18
  • -Recibidos: 6
  • Mensajes: 79
  • Calificaciones: +16/-2
  • Sexo: Masculino
  • Escribiendo archivos .pas desde 1991.
    • Rescatando a Delphi
Re:Rutinas pequeñas que pueden ayudar
« Respuesta #20 en: 09 de Febrero de 2009, 23:49:25 »
¡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:

Código DELPHI
  1.   Function Uno (Const Valor :Boolean) :Integer;
  2.   Begin
  3.     Result := (Byte (Valor) * 2) - 1;
  4.   End;
  5.  

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.

Código DELPHI
  1. Position := Position + Uno (GoForward);

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

Uno (abrazo);

Al González. :)
« última modificación: 10 de Febrero de 2009, 07:39:31 por enecumene »


■ Conoce mi bitácora.  ■ Escucho propuestas para trabajar fuera de México.

Desconectado Héctor Randolph

  • Administrador
  • ******
  • Gracias
  • -Dados: 28
  • -Recibidos: 93
  • Mensajes: 486
  • Calificaciones: +105/-0
  • Sexo: Masculino
  • 501st Legion
Re:Rutinas pequeñas que pueden ayudar
« Respuesta #21 en: 10 de Febrero de 2009, 10:27:05 »
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.

Código 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;
  32.  


Ejemplo de uso:

Código DELPHI
  1.   ShowMessageFmt('La distancia entre kitten y sitting es : %d',[DistanciaLevenshtein('kitten','sitting')]);
  2.  

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

Desconectado poliburro

  • Administrador
  • ******
  • Gracias
  • -Dados: 56
  • -Recibidos: 134
  • Mensajes: 2,048
  • Calificaciones: +155/-0
  • Sexo: Masculino
Re:Rutinas pequeñas que pueden ayudar
« Respuesta #22 en: 10 de Febrero de 2009, 10:51:23 »
Interesante algoritmo amigo hector muchas gracias por la aportación
Mi corazón late a la izquierda

Desconectado seoane

  • Administrador
  • ******
  • Gracias
  • -Dados: 33
  • -Recibidos: 179
  • Mensajes: 762
  • Calificaciones: +193/-0
  • Sexo: Masculino
  • Procrastinando ...
    • Mi Web
Re:Rutinas pequeñas que pueden ayudar
« Respuesta #23 en: 15 de Febrero de 2009, 12:11:59 »
Comprobar si una dirección ip es valida.

Código 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));
  10.  

Desconectado escafandra

  • Moderadores
  • ******
  • Gracias
  • -Dados: 83
  • -Recibidos: 565
  • Mensajes: 2,131
  • Calificaciones: +604/-0
  • Sexo: Masculino
Re:Rutinas pequeñas que pueden ayudar
« Respuesta #24 en: 24 de Febrero de 2009, 10:13:28 »
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.

Código 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*b  + 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.
« última modificación: 24 de Febrero de 2009, 16:14:32 por escafandra »

Desconectado seoane

  • Administrador
  • ******
  • Gracias
  • -Dados: 33
  • -Recibidos: 179
  • Mensajes: 762
  • Calificaciones: +193/-0
  • Sexo: Masculino
  • Procrastinando ...
    • Mi Web
Re:Rutinas pequeñas que pueden ayudar
« Respuesta #25 en: 09 de Abril de 2009, 06:54:54 »
Obtener los archivos de un directorio ordenados por fecha de modificación:
Código 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;
  19.  

Por ejemplo:
Código 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;
  12.  

Desconectado egostar

  • Administrador
  • ******
  • Gracias
  • -Dados: 812
  • -Recibidos: 435
  • Mensajes: 8,120
  • Calificaciones: +488/-7
  • Sexo: Masculino
  • coding my life
    • MeXistemas punto com
Re:Rutinas pequeñas que pueden ayudar
« Respuesta #26 en: 09 de Abril de 2009, 09:32:12 »
Como siempre amigo seoane, pones código que me va a servir y en el momento justo (y)

Salud OS

"Si no quieres que la gente se olvide de ti apenas te mueras, escribe algo que valga la pena leerse o valga la pena escribirse."

- Benjamin Franklin


         

Desconectado Caral

  • Administrador
  • ******
  • Gracias
  • -Dados: 195
  • -Recibidos: 258
  • Mensajes: 3,232
  • Calificaciones: +300/-4
  • Sexo: Masculino
  • Siempre Novato
Re:Rutinas pequeñas que pueden ayudar
« Respuesta #27 en: 09 de Abril de 2009, 09:47:53 »
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