Perl en Español

  1. Home
  2. Tutoriales
  3. Foro
  4. Artículos
  5. Donativos
  6. Publicidad
 

Hash

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico
Mensaje Mie Jul 30, 2008 2:16 pm
afry
Perlero Nuevo
Perlero Nuevo
Registrado: 05 Jul 2008
Mensajes: 11
Hash Responder citando

Hola, me gustaría saber qué es lo que significan de forma detallada, a poder ser, las condiciones y las instrucciones que se precisan en este bucle que es el fragmento de un programa:

Perl:
foreach my $key (keys %hash) {
    $flag = 0;
    my $B = $hash{$key};
    foreach my $key2 (keys %hash) {
        my $B2 = $hash{$key2};
        if($B2==$B && $key2!=$key && $key2<$key) {
            $flag=1;
        }
    }

    if ($flag == 1) {
        delete $hash{$key};
    }
}


Muchas gracias, espero respuesta
Mensaje Mie Jul 30, 2008 2:40 pm
explorer
Moderador
Moderador
Registrado: 24 Jul 2005
Mensajes: 4089
Ubicación: Valladolid, España
Responder citando

Código:
* Para todas las claves de un hash
*   Ponemos una bandera a 0
*   Obtenemos el valor asociado a esa clave
*   Para todas las claves del mismo hash
*       Obtenemos el valor asociado a esa clave
*       Si los dos valores son iguales, y,
*       Si las dos claves son distintas, y,
*       Si la primera clave es mayor que la segunda
*           entonces la bandera se pone a 1
*   Fin del bucle
*   Si la bandera está a 1 (hemos encontrado una clave que es menor que la de búsqueda)
*       Borramos el elemento hash
* Fin del bucle


Creo que, más o menos, lo que hace es eliminar los elementos de un hash que, a igualdad de valores, tenga una clave compañera de menor valor. El resultado final es que quedan claves de cada vez menor valor numérico.
Mensaje Vie Ago 01, 2008 1:27 pm
Jenda
Perlero Frecuente
Perlero Frecuente
Registrado: 29 Oct 2007
Mensajes: 104
Ubicación: Praga, Republica Checa
Responder citando

Hay otras y mejores formas para hacer esto. El problema con esa solución es que es de complejidad O(n*n). Más comprensiblemente, que el tiempo necesario para completarlo sube bastante rápidamente con el número de claves en el hash. Si el número de claves se dobla, el tiempo se cuadruplica (pues, después de traspasar algún número, el O() significa que hay algunas constantes que necesitaríamos si quisiéramos computar el tiempo necesario, pero no nos importan ahora. Ver http://es.wikipedia.org/wiki/Cota_superior_asint%C3%B3tica )

Aquí hay otras dos posibilidades:
Perl:

{
        my %tmp;
        foreach my $key (sort keys %hash) {
                $tmp{$hash{$key}} = $key unless exists $tmp{$hash{$key}};
        }
        %hash = reverse %tmp;
}

o
Perl:

{
        my %tmp;
        foreach my $key (keys %hash) {
                $tmp{$hash{$key}} = $key if !exists $tmp{$hash{$key}} or $tmp{$hash{$key}} > $key;
        }
        %hash = reverse %tmp;
}

La primera es O(n*log(n)), la segunda O(n). Ambas usan el otro hash. El otro hash nos ayuda a obtener los valores únicos.

Espero que explorer puede ponerlo más claro, mi español es terrible.

Jenda
Mensaje Vie Ago 01, 2008 1:51 pm
Jenda
Perlero Frecuente
Perlero Frecuente
Registrado: 29 Oct 2007
Mensajes: 104
Ubicación: Praga, Republica Checa
Responder citando

Actualmente el primer código es inútilmente complejo. Se puede simplificar en
Perl:

{
        my %tmp;
        foreach my $key (sort {$b <=> $a} keys %hash) {
                $tmp{$hash{$key}} = $key;
        }
        %hash = reverse %tmp;
}

o
Perl:

{
        my %seen;
        foreach my $key (sort keys %hash) {
                delete $hash{$key} if $seen{$hash{$key}}++;
        }
}
Publicar nuevo tema   Responder al tema    Foros de discusión -> Básico Todas las horas son GMT - 6 Horas
Página 1 de 1



Powered by phpBB © 2001, 2005 phpBB Group