Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

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

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 15-05-2010
Kandorf Kandorf is offline
Miembro
 
Registrado: may 2007
Posts: 38
Poder: 0
Kandorf Va por buen camino
Red face Odenar Cadenas con letras y números

Hola, estoy usando un TStrings y sé ordenarlo, el problema me surge en que este contiene números dentro de las cadenas, además no tienen por qué estar al principio de la cadena y puede o no contenerlos. No he encontrado solución para este caso particular.

Un ejemplo de cómo ordenaría es:
10 perro
3 casa
hola 200 lalala
hola 33 lalala
hola 4 adiós

Mientras que el orden correcto sería:
3 casa
10 perro
hola 4 adiós
hola 33 lalala
hola 200 lalala

(Disculpad por el ejemplo tan sumamente tonto e infantil, estoy espesito)

Lo que se me ha ocurrido es, al ordenar como ya lo hago, buscar la longitud máxima de los números de las dos cadenas y hacer que todos la tengan, poniendo 0s delante, pero no sé si esto sería muy ineficiente.

Os preguntaba por si hay alguna manera más eficiente, en caso contrario yo mismo construiré la función, ese no es el problema.

Saludos y gracias por vuestro tiempo.
Responder Con Cita
  #2  
Antiguo 15-05-2010
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola kandorf.

No conozco la existencia de algo predefinido que evalue "cuantitativamente"
los caracteres que representan un valor numérico. Dentro de una cadena los
caracteres serán ordenados por su valor ASCII, por lo que 10, siempre será
menor a 3, puesto que alfabéticamente el 1 precede al 3.

Creo que como decis en el post, vas a tener que realizar una función que
busque dígitos numéricos y si los hay, realize la conversíon numérica para
luego realizar su reordenación, basada en la nueva regla que vos le impones.

Por supuesto que no podrías usar propiedades como Sorted de TStringList,
puesto que alteraría el órden impuesto por tu función.

Saludos.
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #3  
Antiguo 16-05-2010
Kandorf Kandorf is offline
Miembro
 
Registrado: may 2007
Posts: 38
Poder: 0
Kandorf Va por buen camino
Bueno, ya he hecho las funciones para ordenar correctamente, las posteo por si le resulta últil a alguien.
En realidad ordena un StringGrid dada una columna, pero vale con sustituir "Cells[Columna,i]" por "Cadenas[i]", suponiendo que el TStrings se llame Cadenas:
Código Delphi [-]
// Devuelve la longitud máxima de las cifras de un String
function FStrMaxLongitudCifra(Cadena: String): Integer;
var
  i, j: Integer;
  MaxLongitud: Integer;
begin
  MaxLongitud:=0;
  i:=1;
  while i<=Length(Cadena) do begin
    if (CompareStr(Cadena[i],IntToStr(0))>=0) and (CompareStr(Cadena[i],IntToStr(9))<=0) then begin
      j:=1;
      while (i+j<=Length(Cadena)) and (CompareStr(Cadena[i+j],IntToStr(0))>=0) and (CompareStr(Cadena[i+j],IntToStr(9))<=0) do
        Inc(j);
      if j>MaxLongitud then
        MaxLongitud:=j;
      i:=i+j;
    end else
      Inc(i);
  end;
  Result:=MaxLongitud;
end;

// Da a los números de una cadena la longitud especificada añadiendo 0s a los lados
function FStrAgrandarNúmeros(Cadena: String; Longitud: Integer): String;
var
  i, j: Integer;
begin
  if Longitud>0 then begin
    if Longitud>=3 then
      Longitud:=Longitud;
    i:=1;
    while i<=Length(Cadena) do begin
      if (CompareStr(Cadena[i],IntToStr(0))>=0) and (CompareStr(Cadena[i],IntToStr(9))<=0) then begin
        j:=1;
        while (i+j<=Length(Cadena)) and (CompareStr(Cadena[i+j],IntToStr(0))>=0) and (CompareStr(Cadena[i+j],IntToStr(9))<=0) do
          Inc(j);
        Cadena:=Copy(Cadena,0,i-1)+DupeString('0',Longitud-j)+Copy(Cadena,i,Length(Cadena));
        i:=i+Longitud;
      end else
        Inc(i);
    end;
  end;
  Result:=Cadena;
end;

// Ordena un StringGrid dado una columna que puede contener Letras y Números
procedure FStgOrdenarLN(Grid : TStringGrid; Columna:integer);
var
   i, j: Integer;
   Temp: TStringList;
   AuxCadena1, AuxCadena2: String;
   Longitud1, MaxLongitudNúmero: Integer;
begin
  Temp:=TStringList.Create;
  with Grid do begin
    for i:=FixedRows to RowCount-2 do begin
      // Las dos siguientes líneas las hago fuera en un intento de reducir el número de llamadas a las funciones, más abajo se repiten otra vez
      AuxCadena1:=Cells[Columna,i];
      Longitud1:=FStrMaxLongitudCifra(AuxCadena1);
      for j:=i+1 to rowcount-1 do begin
        AuxCadena2:=Cells[Columna,j];
        MaxLongitudNúmero:=FStrMaxLongitudCifra(AuxCadena2);
        if Longitud1>MaxLongitudNúmero then
          MaxLongitudNúmero:=Longitud1;
        if AnsiCompareText(FStrAgrandarNúmeros(AuxCadena1,MaxLongitudNúmero),FStrAgrandarNúmeros(AuxCadena2,Max  LongitudNúmero))>0 then begin
          Temp.assign(rows[j]);
          rows[j].assign(rows[i]);
          rows[i].assign(Temp);
          // Aquí repito las funciones mencionadas anteriormente, ya que la Cadena de referencia cambia
          AuxCadena1:=Cells[Columna,i];
          Longitud1:=FStrMaxLongitudCifra(AuxCadena1);
        end;
      end;
    end;
  end;
  temp.free;
end;
Espero que resulte útil a alguien.

Por favor, opinen, el tiempo de proceso aumenta y se nota, yo estoy ordenando actualmente 625 cadenas bastante largas.
Estaría encantado de que me corrigiérais la función

Saludos.
Responder Con Cita
  #4  
Antiguo 20-05-2010
Kandorf Kandorf is offline
Miembro
 
Registrado: may 2007
Posts: 38
Poder: 0
Kandorf Va por buen camino
No puedo editar mi anterior mensaje...
Tiene un fallo el código, donde pone:
Código Delphi [-]
// Da a los números de una cadena la longitud especificada añadiendo 0s a los lados
function FStrAgrandarNúmeros(Cadena: String; Longitud: Integer): String;
var
  i, j: Integer;
begin
  if Longitud>0 then begin
    if Longitud>=3 then
      Longitud:=Longitud;
    i:=1;
El "if Longitud>=3" lo puse para probar el código y poner un breackpoint ahí, quedaría
Código Delphi [-]
function FStrAgrandarNúmeros(Cadena: String; Longitud: Integer): String;
var
  i, j: Integer;
begin
  if Longitud>1 then begin // Con 1 sería más eficiente, todo número ya va a tener como mínimo 1 de longitud, así que no habría que agrandarlo
    //Quito las líneas del if, que no valen para nada
    i:=1
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
Numeros a letras citlalliDgp Varios 6 19-03-2009 07:14:54
Numeros y letras Caral Varios 11 28-03-2008 18:22:53
Numeros En Letras Cañones Impresión 2 11-06-2007 23:55:12
Numeros a Letras!! jmedina Varios 26 20-10-2005 20:19:42
trasformar numeros a letras NestorN Varios 1 17-09-2005 01:33:44


La franja horaria es GMT +2. Ahora son las 00:28:13.


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