¿Cuál es la forma más fácil de obtener una clave con el valor más alto de un hash en Perl?¿Cuál es la forma más fácil de obtener una clave con el valor más alto de un hash en Perl?
Respuesta
Si bien la solución con una especie:
(sort {$hash{$a} <=> $hash{$b}} keys %hash)[0]
encontrado en algunas de las otras respuestas es bastante elegante, no funciona tan bien como se ve. En primer lugar, el género transforma una operación de búsqueda de búsqueda O(n)
en una O(n log n)
. En segundo lugar, la solución de clasificación tiene n log n
hash ups. Las búsquedas de hash son muy buenas para ciertas operaciones, pero cuando se trabaja con todo el hash, las búsquedas serán más lentas que con each
, keys
o values
para iterar a través de la estructura de datos. Esto se debe a que los iteradores no necesitan calcular los hash de las claves, ni necesitan recorrer repetidamente los contenedores para encontrar los valores. Y la sobrecarga no es constante, sino que aumenta a medida que los hash aumentan.
Estas son algunas soluciones rápidas:
use strict;
use warnings;
my %hash = (
small => 1,
medium => 5,
largest => 10,
large => 8,
tiny => 0.1,
);
que aquí hay una solución utilizando el iterador each
(una operación O(1)
hecho n
veces):
sub largest_value (\%) {
my $hash = shift;
keys %$hash; # reset the each iterator
my ($large_key, $large_val) = each %$hash;
while (my ($key, $val) = each %$hash) {
if ($val > $large_val) {
$large_val = $val;
$large_key = $key;
}
}
$large_key
}
print largest_value %hash; # prints 'largest'
O una versión más rápida que comercia memoria para velocidad (hace una copia del hash):
sub largest_value_mem (\%) {
my $hash = shift;
my ($key, @keys) = keys %$hash;
my ($big, @vals) = values %$hash;
for (0 .. $#keys) {
if ($vals[$_] > $big) {
$big = $vals[$_];
$key = $keys[$_];
}
}
$key
}
print largest_value_mem %hash; # prints 'largest'
Aquí es el rendimiento con diferentes tamaños de hash:
10 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 111565/s -- -8% -13%
largest_value 121743/s 9% -- -5%
largest_value_mem 127783/s 15% 5% --
50 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 24912/s -- -37% -40%
largest_value 39361/s 58% -- -6%
largest_value_mem 41810/s 68% 6% --
100 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 9894/s -- -50% -56%
largest_value 19680/s 99% -- -12%
largest_value_mem 22371/s 126% 14% --
1,000 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 668/s -- -69% -71%
largest_value 2183/s 227% -- -7%
largest_value_mem 2341/s 250% 7% --
10,000 keys: Rate largest_with_sort largest_value largest_value_mem
largest_with_sort 46.5/s -- -79% -81%
largest_value 216/s 365% -- -11%
largest_value_mem 242/s 421% 12% --
Como se puede ver, si la memoria no es un gran problema, la versión con arreglos internos es el más rápido, seguido de cerca por el iterador each
, y en un distante tercer lugar ... sort
my $highest_val = (keys {$hash{$b} <=> $hash{$a}} keys %hash)[0];
que devuelve la llave que es el highe valor de st. Supongo que quiere la clave que se asigna al valor más alto. De lo contrario, la pregunta es demasiado simple para preguntar :) (Y en ese caso, ¿por qué no simplemente "claves de ordenación inversa% hash"?) – jrockway
Depende de lo que quiere decir con "valor" aquí. Por lo general, un hash se considera como pares clave/valor, por lo que asumiría lo mismo que jrockway. Pero también podría significar lo que dijo la anfetamaquina. El que pregunta debe aclarar. –
@jrockway - 'Y en ese caso, ¿por qué no solo" claves de ordenación inversa% hash "?' - Porque es una ordenación léxica, y 'ordenar {$ b <=> $ a}' golpea dos pájaros de un tiro en que ambos un tipo numérico Y se invierte. – amphetamachine
Las claves ordenados por valor, de menor a mayor:
sort { $hash{$a} <=> $hash{$b} } keys %hash
Las claves ordenados por valor, de mayor a menor:
reverse sort { $hash{$a} <=> $hash{$b} } keys %hash
y el primer elemento
(reverse sort { $hash{$a} <=> $hash{$b} } keys %hash)[0]
Reemplace la nave espacial con cmp
al gusto.
¿Por qué no simplemente usar 'values' en lugar de' keys'? –
Porque él quiere la clave, no el valor. El valor es qué ordenar, la clave es qué devolver. A menos que esté malinterpretando la pregunta. – jrockway
Ah, vale, lo siento, me lo perdí. –
my $highest_val = (sort { $hash{$a} <=> $hash{$b} } keys %hash)[0];
es probable que sea lo que quiere.
Si usted tiene una muy grande de hash, es posible que desee utilizar algo así como un Schwartzian transformar:
my @array = map {[$hash{$_},$_]} keys %hash;
my $key_with_highest_value = (sort { $a->[0] <=> $b->[0] } @array)[0]->[1]
Esto es más tipeo, pero es O (n) en vez de O (n log n), que generalmente es algo bueno. Si tu lista es grande – jrockway
La transformación Schwartzian aquí solo sirve para reducir el número de búsquedas en la tabla hash, y ** no ** cambia la complejidad de la búsqueda; sigue siendo O (n log n). El enfoque iterativo de @jkasnicki es superior. – Alnitak
El siguiente es más eficiente con el espacio y se ejecutarán en O (n) en lugar de O (n log n) en comparación con las otras respuestas que ordenan el hash. Asume que los valores son enteros mayores que 0 y que el hash no está vacío, sino que debe ampliarse fácilmente para su caso.
my $key_for_max_value;
my $max_value = -1;
while ((my $key, my $value) = each %hash) {
if ($value > $max_value) {
$max_value = $value;
$max_key = $key;
}
}
$ key_for_max_value ahora será la clave correspondiente al valor más alto.
Existe una suposición en su código de que los valores del hash no son todos números negativos menores que -1. Debería simplemente hacer $ max_value el valor de lo primero que se ve o algo así. –
Es bueno saber que alguien por ahí todavía aprecia la eficiencia sobre la falta de habilidad. Buena explicación, también. – amphetamachine
@Kinopiko: Y eso se puede hacer con algo como 'my $ max_value = undef;' y luego, cambiar 'if' por' if (! Defined $ max_value || $ value> $ max_value) '. –
my ($max_key, $max_val) = each %hash or die "hash is empty";
while (my ($key, $val) = each %hash) {
$max_key = $key, $max_val = $val if $val > $max_val;
}
seguro de por qué todo el mundo está haciendo esto a mano ...
use List::Util qw(reduce);
my $max_val_key = reduce { $hash{$a} > $hash{$b} ? $a : $b } keys %hash;
- 1. ¿Cuál es la forma más fácil de animar una línea?
- 2. Obtener el valor más alto de una columna en MongoDB
- 3. Obtener la clave de la matriz con el valor más alto en javascript
- 4. ¿Cuál es la forma más fácil de explicar qué es Hadoop y mapa/reducir?
- 5. ¿Cuál es la forma más fácil de obtener datos espaciales de sql 08 en un mapa?
- 6. ¿Cuál es la forma más fácil de obtener la ubicación actual de un iPhone?
- 7. La forma más fácil de obtener Enum en el par de valores clave
- 8. ¿Cuál es la forma más fácil de instalar un módulo Perl perdido?
- 9. Valor más alto de una matriz asociativa
- 10. C#: ¿cuál es la forma más fácil de restar tiempo?
- 11. ¿Cuál es la forma más fácil de obtener una OutOfMemoryException en C#?
- 12. ¿Cuál es la forma más fácil de acceder a un micrófono de una computadora en Python?
- 13. ¿Cuál es la forma más fácil en Perl puro de transmitir desde otro recurso HTTP?
- 14. ¿Cuál es la forma más concisa de obtener el inverso de un valor booleano de Java?
- 15. ¿La forma más fácil de voltear un valor booleano?
- 16. ¿Cuál es la forma más fácil de analizar un archivo INI en Java?
- 17. ¿Cuál es la forma más rápida de obtener el valor absoluto de un número
- 18. ¿Cuál es la forma más pitonica de proporcionar un valor de retroceso en una tarea?
- 19. ¿Cuál es la forma más defensiva de recorrer líneas en un archivo con Perl?
- 20. Seleccione el segundo valor más alto por clave foránea distinta
- 21. En Ruby, ¿cuál es la forma más limpia de obtener el índice del valor más grande en una matriz?
- 22. Buscar la clave/índice más alto en una matriz
- 23. ¿Cuál es la forma más fácil de convertir la lista con str en list con int?
- 24. ¿Cuál es la forma más fácil de especificar una lista con valores en Spring?
- 25. ¿Es Perl la forma más rápida de escribir una página de alto rendimiento?
- 26. cómo eliminar una clave de un diccionario con el valor más alto?
- 27. ¿Cuál es la forma más fácil de usar el código fuente C en una aplicación Java?
- 28. ¿Cuál es el CMS más fácil de integrar con CakePHP?
- 29. ¿Cuál es la forma más fácil de hacer 'es' en Java?
- 30. ¿Cuál es la forma más fácil de crear una tabla de Excel con C#?
+1 ¡respuesta genial y completa! – Alnitak
Respuesta completa. Sin embargo, un comentario: la complejidad amortizada de una búsqueda hash es O (1), no O (log n). – jkasnicki
comparando las velocidades del mundo real de la búsqueda hash con la búsqueda en matriz todavía muestra una relación no lineal. con 10 elementos, una matriz es% 50 más rápido que un hash, con 10000 elementos es% 100 más rápido, con 1,000,000 de elementos es 210% más rápido ... –