Qual è il modo più semplice per ottenere una chiave con il valore più alto da un hash in Perl?Qual è il modo più semplice per ottenere una chiave con il valore più alto da un hash in Perl?
risposta
Mentre la soluzione con un ordine:
(sort {$hash{$a} <=> $hash{$b}} keys %hash)[0]
si trovano in alcune delle altre risposte è molto elegante, ma non esegue come bene come sembra. Prima di tutto, l'ordinamento trasforma un'operazione di ricerca di ricerca O(n)
in uno O(n log n)
. In secondo luogo, la soluzione di ordinamento ha le ricerche di hash n log n
. Le ricerche hash sono molto adatte per determinate operazioni, ma quando si lavora con l'intero hash, le ricerche saranno più lente dell'uso di each
, keys
o values
per scorrere la struttura dei dati. Questo perché gli iteratori non hanno bisogno di calcolare gli hash delle chiavi, né hanno bisogno di passare ripetutamente attraverso i contenitori per trovare i valori. E l'overhead non è costante, ma aumenta man mano che gli hash diventano più grandi.
Ecco alcune soluzioni più rapide:
use strict;
use warnings;
my %hash = (
small => 1,
medium => 5,
largest => 10,
large => 8,
tiny => 0.1,
);
Ecco una soluzione che utilizza il each
iteratore (un'operazione O(1)
fatto n
volte):
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 versione più veloce che commercia memoria per velocità (fa una copia dell'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'
Ecco le prestazioni con i vari formati 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% --
Come si può vedere, se la memoria non è molto più di un problema, la versione con le matrici interne è più veloce, seguito da vicino dal each
iteratore, e in un terzo lontana ... sort
my $highest_val = (keys {$hash{$b} <=> $hash{$a}} keys %hash)[0];
che restituisce la chiave che è il highe valore st Presumo che voglia la chiave che mappa al valore più alto. Altrimenti, la domanda è troppo semplice per essere posta :) (E in tal caso, perché non solo "reverse sort keys% hash"?) – jrockway
Dipende da cosa intendi per "valore" qui. Di solito un hash è pensato come coppia chiave/valore, quindi assumerei la stessa cosa di jrockway. Ma potrebbe anche significare cosa diceva l'amfetamachina. L'interrogante dovrebbe chiarire. –
@jrockway - 'E in tal caso, perché non solo" reverse sort keys% hash "?' - Perché quello è un ordinamento lessicale, e 'sort {$ b <=> $ a}' colpisce due piccioni con una fava in quanto è entrambi un tipo numerico E è invertito. – amphetamachine
Le chiavi ordinati per valore, dal più basso al più alto:
sort { $hash{$a} <=> $hash{$b} } keys %hash
Le chiavi ordinati per valore, dal più alto al più basso:
reverse sort { $hash{$a} <=> $hash{$b} } keys %hash
E il primo elemento
(reverse sort { $hash{$a} <=> $hash{$b} } keys %hash)[0]
Sostituire l'astronave con cmp
a piacere.
Perché non usare solo 'valori' invece di' chiavi'? –
Perché vuole la chiave, non il valore. Il valore è cosa ordinare, la chiave è cosa restituire. A meno che non fraintenda la domanda. – jrockway
Ah, OK, scusa, mi sono perso. –
my $highest_val = (sort { $hash{$a} <=> $hash{$b} } keys %hash)[0];
è probabilmente quello che vuoi.
Se si dispone di un grande hash, si potrebbe desiderare di usare qualcosa come un Trasformata di Schwartz:
my @array = map {[$hash{$_},$_]} keys %hash;
my $key_with_highest_value = (sort { $a->[0] <=> $b->[0] } @array)[0]->[1]
Questa è più tipizzazione, ma è O (n) invece di O (n log n), che è generalmente una buona cosa. Se la tua lista è grande. – jrockway
La trasformazione di Schwartzian qui serve solo a ridurre il numero di ricerche nella tabella hash, e ** non ** modifica la complessità della ricerca - è ancora O (n log n). L'approccio iterativo di @jkasnicki è superiore. – Alnitak
Quello che segue è più spazio-efficiente e verrà eseguito in O (n) invece di O (n log n) rispetto alle altre risposte che ordinano l'hash. Si assume che i valori siano numeri interi maggiori di 0 e che l'hash non sia vuoto, ma che dovrebbe essere facilmente esteso per il tuo 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 sarà la chiave corrispondente al valore più alto.
Nel codice è presente un'ipotesi che i valori dell'hash non siano tutti numeri negativi inferiori a -1. Dovresti solo fare di $ max_value il valore della prima cosa vista o qualcosa del genere. –
È bello sapere che qualcuno là fuori apprezza ancora l'efficienza rispetto all'affidabilità. Buona spiegazione, anche. – amphetamachine
@Kinopiko: E ciò può essere fatto con qualcosa come "my $ max_value = undef;" e più tardi, cambia 'if' in' 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;
}
Non so perché ognuno sta facendo tutto a mano ...
use List::Util qw(reduce);
my $max_val_key = reduce { $hash{$a} > $hash{$b} ? $a : $b } keys %hash;
- 1. Ottenere chiave con il valore più alto da oggetto
- 2. stampa il valore più alto in dict con chiave
- 3. Ottenere il valore più alto di una colonna in MongoDB
- 4. Qual è il modo più semplice in Javascript per ottenere solo il segno di un numero?
- 5. Seleziona il secondo valore più alto per chiave esterna distinta
- 6. Il modo più efficiente per ottenere diversi hash in Redis?
- 7. il modo più semplice per incorporare Perl in html
- 8. Qual è il modo più semplice in C# per tagliare una nuova riga da una stringa?
- 9. Qual è il modo più semplice per sottrarre un mese da una data in Python?
- 10. Esiste un modo più semplice per creare il pacchetto perl
- 11. Qual è il modo più semplice per spiegare Che cos'è Hadoop e Mappa/Riduci?
- 12. Un buon modo per ottenere la chiave del valore più alto di un dizionario in C#
- 13. Qual è il modo corretto di stampare un elenco annidato con il valore più alto in Python
- 14. Qual è il modo più semplice per scambiare il char in una stringa con Python?
- 15. Trovare il valore più alto in un'enumerazione
- 16. Qual è il modo più semplice per ottenere una OutOfMemoryException in C#?
- 17. Qual è il modo più semplice per rimuovere tutti gli attributi da un XML in C#?
- 18. Qual è il modo più difensivo per scorrere le righe in un file con Perl?
- 19. Qual è il modo più semplice per mantenere oggetti java?
- 20. Qual è il modo più semplice per usare reify (ottenere un AST di) un'espressione in Scala?
- 21. Qual è il modo più semplice per ottenere dati spaziali sql 08 su una mappa?
- 22. C#: qual è il modo più semplice per sottrarre tempo?
- 23. Qual è il modo più semplice per ottenere questi dati in un Dataframe Pandas?
- 24. Qual è il "modo rubino" per analizzare una stringa per una singola chiave/valore?
- 25. Il modo più semplice per capovolgere un valore booleano?
- 26. Qual è il modo più semplice per visualizzare httpServletResponse.sendError (403, "Il mio messaggio") Stato da JSTL
- 27. Qual è il modo più semplice per combinare più raccolte in uno stream in Java?
- 28. Qual è il modo migliore per copiare in profondità un hash di hash in Perl?
- 29. Qual è il modo più semplice per ottenere tfidf con dataframe panda?
- 30. Qual è il modo più semplice per connettere un dispositivo a un iPad da un'applicazione?
+1 risposta completa e approfondita! – Alnitak
Risposta completa. Un commento però: la complessità ammortizzata di una ricerca hash è O (1), non O (log n). – jkasnicki
confrontando le velocità reali della ricerca di hash alla ricerca di array continua a mostrare una relazione non lineare. con 10 elementi, un array è% 50 più veloce di un hash, con 10000 elementi è% 100 più veloce, con 1.000.000 di elementi è più veloce del 210% ... –