यदि किसी सरणी के दो अधिकतम तत्व हैं?

Nov 25 2020

इस कोड में यदि उपयोगकर्ता 2, दो बार और 1, दो बार टाइप करता है। फिर दो अधिकतम तत्व हैं और किंडर और ट्विक्स दोनों को मुद्रित किया जाना चाहिए। पर कैसे ? मैं शायद अगर विधि के साथ ऐसा कर सकता हूं, लेकिन इससे मेरा कोड और भी लंबा हो जाएगा। कोई शांत संस्करण? क्या मैं ऐसा सिर्फ एक के साथ कर सकता हूं?

a = [0, 0, 0,]
b = ["Kinder", "Twix", "Mars"]

while true 
  input = gets.chomp.to_i
  if input == 1
    a[0] += 1
  elsif input == 2
    a[1] += 1
  elsif input == 3 
    a[2] += 1
  elsif input == 0 
    break
  end 
end

index = a.index(a.max)
chocolate = b[index] if index
print a.max,chocolate
 

जवाब

5 CarySwoveland Nov 25 2020 at 04:15

सवाल वास्तव में सरणी aके निर्माण के साथ कुछ नहीं करना है।

def select_all_max(a, b)
  mx = a.max
  b.values_at(*a.each_index.select { |i| a[i] == mx })
end
b = ["Kinder", "Twix", "Mars"]
p select_all_max [0, 2, 1], b
["Twix"]

p select_all_max [2, 2, 1], b
["Kinder", "Twix"]

देखें Array # मान_at ।


यह वैकल्पिक रूप से एक पास में किया जा सकता है।

def select_all_max(a, b)
  b.values_at(
    *(1..a.size-1).each_with_object([0]) do |i,arr|
      case a[i] <=> arr.last
      when 0
        arr << i
      when 1
        arr = [i]
      end
    end
  )
end
p select_all_max [0, 2, 1], b
["Twix"]

p select_all_max [2, 2, 1], b
["Kinder", "Twix"]

p select_all_max [1, 1, 1], b
["Kinder", "Twix", "Mars"]
2 maxpleaner Nov 25 2020 at 04:06

एक तरीका इस प्रकार होगा:

सबसे पहले, इनपुट-जमा को गिनती से अलग करें, इसलिए हम इस चरण में इनपुट एकत्र करेंगे:

inputs = []
loop do
  input = gets.chomp.to_i
  break if input.zero?
  inputs << input 
end

अब हम इनपुट्स को टैली कर सकते हैं। यदि आपके पास रूबी 2.7 है तो आप बस counts_by_input = inputs.tallyप्राप्त करने के लिए कर सकते हैं { "Twix" => 2, "Kinder" => 2 }। अन्यथा, मेरा पसंदीदा तरीका ट्रांसफॉर्म_वेल्यूज़ के साथ group_by का उपयोग करना है :

counts_by_input = inputs.group_by(&:itself).transform_values(&:count)
# => { "Twix" => 2, "Kinder" => 2 }

अब, क्योंकि हम उनकी गिनती के आधार पर मान निकाल रहे हैं, हम चाहते हैं कि गिनती के रूप में हो। आम तौर पर हम हैश उल्टा कर सकते हैं , लेकिन यह इस मामले में काम नहीं करेगा क्योंकि यह हमें प्रति कुंजी केवल एक मूल्य देगा, और आपको इसकी आवश्यकता नहीं होगी:

inputs_by_count = counts_by_input.invert
# => { 2 => "Kinder" }
# This doesn't work, it removed one of the values

इसके बजाय, हम एक group_by और का उपयोग कर सकते हैं transform_values(कारण मुझे इन विधियों को पसंद है क्योंकि वे बहुत बहुमुखी हैं ...):

inputs_by_count = counts_by_input.
  group_by { |input, count| count }.
  transform_values { |keyvals| keyvals.map(&:first) }
# => { 2 => ["Twix", "Kinder"] }

यहां transform_valuesकोड शायद थोड़ा भ्रमित करने वाला है, लेकिन समझने के लिए एक महत्वपूर्ण बात यह है कि कई बार, हैश पर एन्युमरेबल तरीकों को कॉल करना उन्हें [[key1, val1], [key2, val2]]सरणियों में परिवर्तित करता है :

counts_by_input.group_by { |input, count| count }
# => { 2 => [["Twix", 2], ["Kinder", 2]] }

यही कारण है कि हम transform_values { |keyvals| keyvals.map(&:first) }अपने वांछित प्रारूप को प्राप्त करने के लिए बाद में कॉल करते हैं{ 2 => ["Twix", "Kinder"] }

वैसे भी, इस समय हमारा परिणाम प्राप्त करना बहुत आसान है:

inputs_by_count[inputs_by_count.keys.max]
# => ["Twix", "Kinder"]

मुझे पता है कि यह सब शायद थोड़ा पागल लगता है, लेकिन जब आप एन्युमरेबल तरीकों से परिचित हो जाते हैं तो आप इस तरह के डेटा ट्रांसफ़ॉर्मेशन को बहुत तेज़ी से कर पाएंगे।

टीएल; डॉ।, मुझे कोडज़ दें

inputs = []
loop do
  input = gets.chomp.to_i
  break if input.zero?
  inputs << input 
end

inputs_by_count = inputs.
  group_by(&:itself).
  transform_values(&:count).
  group_by { |keyvals, count| count }.
  transform_values { |keyvals| keyvals.map(&:first) }

top_count = inputs_by_count.keys.max
inputs_by_count[top_count]
# => ["Twix", "Kinder"]
2 hashrocket Nov 25 2020 at 04:09

इस जैसे किसी और के बारे में क्या राय है:

maximum          = a.max # => 2
top_selling_bars = a.map.with_index { |e, i| b[i] if e == maximum }.compact # => ['Kinder', 'Twix']
p top_selling_bars # => ['Kinder', 'Twix']
1 Stefan Nov 25 2020 at 14:55

यदि आपके पास है

a = [2, 2, 0,]
b = ['Kinder', 'Twix', 'Mars']

आप इसके aमाध्यम से अधिकतम मूल्य की गणना कर सकते हैं :

max = a.max #=> 2

और उस मान के अनुसार सभी तत्वों को खोजें:

b.select.with_index { |_, i| a[i] == max }
#=> ["Kinder", "Twix"]