2010-05-22 2 views

उत्तर

32

जबकि तरह से समाधान:

(sort {$hash{$a} <=> $hash{$b}} keys %hash)[0] 

अन्य उत्तर में से कुछ में पाया काफी सुंदर है, यह के रूप में अच्छी तरह से के रूप में यह लग रहा है प्रदर्शन नहीं करता। सबसे पहले, इस प्रकार O(n) खोज खोज ऑपरेशन को O(n log n) में बदल देता है। दूसरा, सॉर्ट समाधान में n log n हैश लुक-अप है। हैश लुक-अप कुछ परिचालनों के लिए बहुत अच्छे हैं, लेकिन पूरे हैश के साथ काम करते समय, each, keys, या values का उपयोग डेटा संरचना के माध्यम से करने के लिए लुक-अप धीमा हो जाएगा। ऐसा इसलिए है क्योंकि इटरेटर्स को चाबियों के हैंश की गणना करने की आवश्यकता नहीं होती है, न ही उन्हें मूल्यों को खोजने के लिए बार-बार चलने की आवश्यकता होती है। और ऊपरी भाग स्थिर नहीं है, लेकिन हैश बढ़ने के साथ बढ़ रहा है।

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' 

या एक तेज संस्करण के लिए स्मृति कारोबार:

use strict; 
use warnings; 

my %hash = (
    small => 1, 
    medium => 5, 
    largest => 10, 
    large => 8, 
    tiny => 0.1, 
); 

यहाँ एक समाधान each इटरेटर का उपयोग कर (एक O(1) आपरेशन n बार किया) है:

यहाँ कुछ तेजी से समाधान कर रहे हैं गति (यह हैश की एक प्रति बनाता है):

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' 

यहाँ विभिन्न हैश आकारों के साथ प्रदर्शन है:

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%    -- 

आप देख सकते हैं, अगर स्मृति एक मुद्दे के ज्यादा नहीं है, आंतरिक सरणियों के साथ संस्करण सबसे तेज, है बारीकी से each इटरेटर द्वारा पीछा किया, और में तीसरे स्थान ... sort

+1

+1 से छुटकारा पा सकते हैं महान और गहन उत्तर! – Alnitak

+1

संपूर्ण उत्तर। हालांकि एक टिप्पणी: हैश लुकअप की अमूर्त जटिलता ओ (1) है, ओ नहीं (लॉग एन)। – jkasnicki

+1

हैश लुकअप के लिए हैश लुकअप की असली दुनिया की गति की तुलना में अभी भी एक nonlinear संबंध दिखाता है। 10 तत्वों के साथ, एक सरणी हैश की तुलना में% 50 तेज है, 10000 तत्वों के साथ यह 100% तेज है, 1,000,000 तत्वों के साथ यह 210% तेज है ... –

1
my $highest_val = (keys {$hash{$b} <=> $hash{$a}} keys %hash)[0]; 
+0

कुंजी highe है कि रिटर्न यही कारण है कि सेंट वैल्यू मुझे लगता है कि वह कुंजी चाहता है जो उच्चतम मूल्य पर नक्शा रखता है। अन्यथा, प्रश्न पूछने के लिए बहुत आसान है :) (और उस मामले में, क्यों न सिर्फ "चाबियाँ कुंजी% हैश रिवर्स"?) – jrockway

+2

यह निर्भर करता है कि आपका मतलब "मूल्य" से क्या है। आम तौर पर एक हैश को कुंजी/मूल्य जोड़े के रूप में माना जाता है, इसलिए मैं जेरोवे के समान चीज़ मानता हूं। लेकिन इसका मतलब यह भी हो सकता है कि amphetamachine क्या कहा। प्रश्नकर्ता को स्पष्ट करना चाहिए। –

+0

@ ज्रॉकवे - 'और उस मामले में, क्यों न सिर्फ "रिवर्स सॉर्ट कुंजी% हैश"? - क्योंकि यह एक व्याख्यात्मक प्रकार है, और' क्रमबद्ध करें {$ बी <=> $ ए} 'एक पत्थर के साथ दो पक्षियों को मारता है जिसमें यह दोनों है एक संख्यात्मक प्रकार और यह उलट है। – amphetamachine

4

कुंजी सबसे कम से उच्चतम करने के लिए, मूल्य के अनुसार क्रमबद्ध:

sort { $hash{$a} <=> $hash{$b} } keys %hash 

चाबियाँ, मूल्य के अनुसार क्रमबद्ध उच्चतम से न्यूनतम:

reverse sort { $hash{$a} <=> $hash{$b} } keys %hash 

और पहला तत्व

(reverse sort { $hash{$a} <=> $hash{$b} } keys %hash)[0] 

स्पेसशिप को 012 के साथ बदलें स्वाद के लिए।

+0

क्यों नहीं 'कुंजी' के बजाय 'मान' का उपयोग करें? –

+0

क्योंकि वह कुंजी चाहता है, मूल्य नहीं। मूल्य यह है कि किस प्रकार सॉर्ट करना है, कुंजी वापस लौटना है। जब तक मैं सवाल गलत नहीं कर रहा हूं। – jrockway

+0

आह, ठीक है, क्षमा करें, मुझे याद आया। –

1
my $highest_val = (sort { $hash{$a} <=> $hash{$b} } keys %hash)[0]; 

आप जो चाहते हैं वह होने की संभावना है।

my @array = map {[$hash{$_},$_]} keys %hash; 
my $key_with_highest_value = (sort { $a->[0] <=> $b->[0] } @array)[0]->[1] 
+0

के बजाय' $ हैश {$ बी} <=> $ हैश {$ a} 'का उपयोग करें यह अधिक टाइपिंग है, लेकिन ओ (एन) के बजाय ओ (एन) है लॉग एन), जो आम तौर पर एक अच्छी बात है। यदि आपकी सूची बड़ी है। – jrockway

+1

यहां श्वार्टज़ियन परिवर्तन केवल हैश टेबल लुकअप की संख्या को कम करने में कार्य करता है, और ** ** ** ** खोज की जटिलता को नहीं बदलता है - यह अभी भी ओ (एन लॉग एन) है। @jkasnicki से पुनरावृत्त दृष्टिकोण बेहतर है। – Alnitak

6

निम्नलिखित अधिक स्थान-कुशल है और हे (एन) में चलेंगे हे के बजाय (एन:

आप एक बहुत बड़े हैश है, तो आप को बदलने के लिए एक Schwartzian की तरह कुछ का उपयोग करना चाहें लॉग एन) हैश को सॉर्ट करने वाले अन्य उत्तरों की तुलना में। यह मानता है कि मान 0 से अधिक पूर्णांक हैं और हैश खाली नहीं है, लेकिन आपके मामले के लिए आसानी से बढ़ाया जाना चाहिए।

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 अब उच्चतम मूल्य के अनुरूप कुंजी होगी।

+4

आपके कोड में एक धारणा है कि हैश के मान सभी नकारात्मक संख्या -1 से कम नहीं हैं। आपको केवल पहली चीज़ या मूल्य की अधिकतम चीज़ $ अधिकतम_वल्यू बनाना चाहिए। –

+3

_someone_ जानने के लिए अच्छा है अभी भी शॉर्ट-हाथ पर दक्षता की सराहना करता है। अच्छी व्याख्या भी। – amphetamachine

+0

@ किनोपिको: और यह 'मेरे $ max_value = undef;' जैसे कुछ के साथ किया जा सकता है और बाद में, 'if' to 'if (! $ Max_value || $ value> $ max_value परिभाषित किया गया है)'। उचित रूप से आकार के डेटा सेट के लिए –

3
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; 
} 
9
नहीं

यकीन है कि क्यों हर कोई हाथ से यह कर रहा है ...

use List::Util qw(reduce); 
my $max_val_key = reduce { $hash{$a} > $hash{$b} ? $a : $b } keys %hash; 
संबंधित मुद्दे

 संबंधित मुद्दे