• Publicidad

Ordenar array de fechas

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

Ordenar array de fechas

Notapor ridomil » 2012-06-12 03:37 @193

Buenas, tengo un problema entre pequeño, mediano y grande.

Me explico: necesito ordenar un array de fechas del siguiente formato: 2012/01/01, 2012/01/01, 1985/01/04, 1995/06/07, 2001/02/02. Bien, este sería el array de fechas @fechas. Asociado a este array relleno otros dos arrays: un array de títulos @titulos y un array de nombres de fichero @nombresDeFichero.

El tema es que las posiciones son correlativas en los tres. Es decir la posición $fechas[0] se corresponde con $titulos[0] y con $nombresDeFichero[0]. Así al intercambiar las fechas debemos intercambiar también las posiciones en el otro array. Lo he intentado de este modo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. ##Implementación del algoritmo quicksort
  2. sub colocar {
  3. ##Debemos adaptar un poco el algoritmo para nuestro
  4. ##Caso concreto de comparación de fechas
  5.     guardarLog("ENTRA EN COLOCAR *************************************************** \n\n\n\n\n\n\n");
  6.  
  7.     my ( @fechas, @titulos, @nombreFichero, $b, $t ) = @_;
  8.  
  9.     for ( my $i = 0; $i < $#fechas; $i++ ) {
  10.         guardarLog( "ARRAY DE FECHAS DENTRO DEL QUICKSORT  " . $fechas[$i] . "\n\n\n" );
  11.     }
  12.  
  13.     my $i;
  14.     my $pivote;
  15.     my $valor_pivote;
  16.     my $temp;
  17.     my $tempTitulos;
  18.     my $tempFicheros;
  19.     ##Objeto de tipo dateTime nos servirá para las comparaciones
  20.     my $Strp = new DateTime::Format::Strptime( pattern => '%Y-%m-%d' );
  21.  
  22.     $pivote = $b;
  23.     ##Valor pivote recoge una de las fechas
  24.     ##El valor del pivote con la fecha parseada
  25.     #Vamos a parsear solo para la comparación
  26.     $valor_pivote = $fechas[$pivote];
  27.     my $valor_pivoteParser = $Strp->parser_dateTime($valor_pivote);
  28.  
  29.     for ( $i = $b + 1; $i <= $t; $i++ ) {
  30.         ##Tenemos que parsear cada elemento que se va a comparar
  31.         my $fechaParser = $Strp->parse_datetime( $fechas[$i] );
  32.         ##Tenemos en este punto las dos fechas con un formato adecuado
  33.         if ( ( DateTime->compare( $fechaParser, $valor_pivoteParser ) == -1 ) ) {
  34.  
  35.             #Antes
  36.             #if($fechas[$i] < $valor_pivote){
  37.  
  38.             ##Intercambios, además del intercambio en el array de fechas
  39.             ##Debemos hacer los intercambios en el array de títulos y
  40.             ##Array de nombre fichero
  41.  
  42.             ##Para el array con las fechas
  43.             $pivote++;
  44.             $temp            = $fechas[$i];
  45.             $fechas[$i]      = $fechas[$pivote];
  46.             $fechas[$pivote] = $temp;
  47.  
  48.             ##Para el array con los títulos
  49.             $tempTitulos      = $titulos[$i];
  50.             $titulos[$i]      = $titulos[$pivote];
  51.             $titulos[$pivote] = $temp;
  52.  
  53.             ##Para el array  con los nombres de fichero
  54.             $tempFicheros           = $nombreFichero[$i];
  55.             $nombreFichero[$i]      = $nombreFichero[$pivote];
  56.             $nombreFichero[$pivote] = $temp;
  57.  
  58.         }
  59.     }
  60.     ##Para la ordenación del array de fechas
  61.     $temp            = $fechas[$b];
  62.     $fechas[$b]      = $fechas[$pivote];
  63.     $fechas[$pivote] = $temp;
  64.  
  65.     ##Ordenamos el array de títulos
  66.     $tempTitulos      = $titulos[$b];
  67.     $titulos[$b]      = $titulos[$pivote];
  68.     $titulos[$pivote] = $tempTitulos;
  69.  
  70.     ##Ordenamos el array con los nombres de los ficheros
  71.     $tempFicheros           = $nombreFichero[$b];
  72.     $nombreFichero[$b]      = $nombreFichero[$pivote];
  73.     $nombreFichero[$pivote] = $tempFicheros;
  74.  
  75.     return $pivote;
  76. }
  77.  
  78. ##Implementación del algoritmo quicksort
  79. ##Nota: Los tres parámetros de la llamada inicial a Quicksort son
  80. ## array[0],0,numero_elementos -1
  81. sub quicksort {
  82.     ##Es una modificación del algoritmo de ordenación quicksort
  83.     ##Al tiempo que ordena el array de fechas tiene que ordenar
  84.     ## el array de títulos y el array de nombre fichero
  85.  
  86.     ##Parámetros que recibe
  87.     my ( $fechas, $titulos, $nombreFichero, $b, $t ) = @_;
  88.     guardarLog("ENTRA EN QUICKSORT *************************************************** \n\n");
  89.     guardarLog( "Valor que llega a quicksort del array de fechas " . $fechas[0] );
  90.     guardarLog( "Valor que llega al quicksort del array de títulos " . $titulos[0] );
  91.     guardarLog( "Valor que llega al quicksort del array de nombreFichero " . $nombreFichero[0] );
  92.     guardarLog( "Valor de la variable b " . $b );
  93.     guardarLog( "Valor de la variable t " . $t );
  94.  
  95.     my $pivote;
  96.     if ( $b < $t ) {
  97.         ##Parámetros:
  98.         ##Array de títulos, de fechas y nombre fichero
  99.         $pivote = colocar( @fechas, @titulos, @nombreFichero, $b, $t );
  100.         quicksort( \@fechas, \@titulos, \@nombreFichero, $b,          $pivote - 1 );
  101.         quicksort( \@fechas, \@titulos, \@nombreFichero, $pivote + 1, $t );
  102.     }
  103.  
  104. }
  105.  
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4


Pero tengo problemas con los pasos por referencia y con los valores repetidos en el array de fechas... que no sé muy bien cómo tratarlos...

Bueno, como siempre, ¡muchas gracias por la ayuda! Un saludo.
Última edición por explorer el 2012-06-12 05:39 @277, editado 2 veces en total
Razón: Formateado de código con Perltidy
ridomil
Perlero nuevo
Perlero nuevo
 
Mensajes: 20
Registrado: 2012-04-24 07:52 @370

Publicidad

Re: Ordenar array de fechas

Notapor explorer » 2012-06-12 05:54 @287

Es muy sencillo...

Debes modificar la subrutina de ordenación para que lo que devuelva sea la lista de índices del array que quieres ordenar. Y una vez que tienes esos índices ordenados, solo te queda reordenar los arrays:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @indices_ordenados = quicksort(...);

@fechas        = @fechas       [@indices_ordenados];
@titulos       = @titulos      [@indices_ordenados];
@nombreFichero = @nombreFichero[@indices_ordenados];
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Re: Ordenar array de fechas

Notapor ridomil » 2012-06-12 06:48 @325

Y ¿qué pasará si hay elementos repetidos en el array de fechas?, que sí puede y de hecho va a suceder...
ridomil
Perlero nuevo
Perlero nuevo
 
Mensajes: 20
Registrado: 2012-04-24 07:52 @370

Re: Ordenar array de fechas

Notapor explorer » 2012-06-12 08:51 @410

Eso lo tiene que resolver quién esté diseñando la rutina de ordenación... Deberá decidir qué hacer en ese caso. Quizás mirar lo que contienen los otros dos array.

Al final, si el resultado es una lista de índices, el código anterior garantiza que están sincronizados entre los tres array.

Hay otra opción: agrupar la información correspondiente a un índice dentro de un mismo objeto. Así, en lugar de tener tres estructuras de datos separados, solo tendrías una.

Más fácil de ordenar, desde luego.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Avanzado

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado