Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

रूबी रिकर्सन और मेमोइज़ेशन में महारत: एक व्यावहारिक गाइड

रूबी में रिकर्सन क्या है?

रिकर्सिव फंक्शन्स वे हैं जो खुद को तब तक कॉल करते रहते हैं जब तक वे एक अंतिम लक्ष्य (जिसे बेस केस के रूप में भी जाना जाता है) तक नहीं पहुंच जाते। प्रत्येक फंक्शन कॉल के बाद आप इस बेस केस की ओर प्रगति करते हैं, जिससे किए जाने वाले काम की मात्रा कम हो जाती है।

एक बार बेस केस पहुंच जाने पर, रिकर्सन समाप्त हो जाता है, और फंक्शन्स वापस लौटना शुरू कर देते हैं।

रूबी रिकर्सन

रिकर्सन के बारे में सीखना शुरू करने के लिए एक क्लासिक उदाहरण फैक्टोरियल संख्या की गणना करना है।

आइए देखते हैं कि हम रूबी में पुनरावृति और रिकर्सन दोनों का उपयोग करके इसे कैसे कर सकते हैं!

एक संख्या का फैक्टोरियल गणना करने के लिए हमें 1 से अपनी लक्ष्य संख्या तक सभी संख्याओं को गुणा करना होगा। उदाहरण के लिए, 5 का फैक्टोरियल है: 1 * 2 * 3 * 4 * 5 = 120।

आइए देखते हैं कि हम रूबी और रिकर्सन का उपयोग करके इसे कैसे कर सकते हैं।

उदाहरण:

 def iterative_factorial(n)
  (1..n).inject(:*)
end
def recursive_factorial(n)
  # बेस केस
  return 1 if n <= 1
  # रिकर्सिव कॉल
  n * recursive_factorial(n-1)
end 

इस उदाहरण में मैं आपको फैक्टोरियल संख्या की गणना करने के दो तरीके दिखाता हूं। पुनरावृत्त और रिकर्सिव समाधान।

रिकर्सिव समाधान में हम उस संख्या को घटाकर प्रगति करते हैं जिस पर हम काम कर रहे हैं (n-1)। एक बार (n <= 1) होने पर कोई और रिकर्सिव कॉल नहीं होते, और यह होता है:

 return 1 # recursive_factorial(1)
return 2 * 1 # recursive_factorial(2)
return 3 * 2 # recursive_factorial(3)
return 4 * 6 # recursive_factorial(4)
return 5 * 24 # recursive_factorial(5)

रूबी डेवलपर्स के रूप में हम ज्यादातर समय पुनरावृत्त समाधान के लिए जाते हैं, और यह बहुत अच्छा है, लेकिन मुझे लगता है कि यह जानना अभी भी उचित है कि रिकर्सन कैसे काम करता है।

अब आइए एक और क्लासिक उदाहरण देखते हैं: फाइबोनैचि संख्याएं।

फाइबोनैचि अनुक्रम

लियोनार्डो फाइबोनैचि ने इस अनुक्रम की खोज तब की जब वे आदर्श परिस्थितियों में खरगोश की आबादी की वृद्धि को मॉडल करने के तरीके की जांच कर रहे थे।

अनुक्रम की गणना वर्तमान से पहले आई दो संख्याओं को जोड़कर की जाती है।

उदाहरण:

1, 1, 2, 3, 5, 8, 13, 21

इसे रूबी में गणना करने के लिए आप एक रिकर्सिव फंक्शन का उपयोग कर सकते हैं:

 def fib(n)
  return n if n < 2
  fib(n-1) + fib(n-2)
end 

इस फंक्शन और एक रेंज का उपयोग करके आप आसानी से पहले 20 फाइबोनैचि नंबरों की गणना कर सकते हैं।

 (1..20).each { |n| puts fib(n) } 

हालांकि, एक समस्या है:

आपका फंक्शन बहुत सारा अतिरिक्त काम कर रहा है जो उसे करने की आवश्यकता नहीं है। इसे स्पष्ट करने के लिए, निम्न छवि देखें।

रूबी रिकर्सन और मेमोइज़ेशन में महारत: एक व्यावहारिक गाइड

छवि में हम देख सकते हैं कि fib(3) की गणना पांच बार की जाती है। यह आपके फंक्शन को वास्तव में धीमा कर देता है यदि आप लंबे फाइबोनैचि अनुक्रमों की गणना करने का प्रयास करते हैं।

समाधान? मेमोइज़ेशन।

मेमोइज़ेशन: पहले से किए गए काम का पुन: उपयोग

क्या यह बहुत अच्छा नहीं होगा यदि आप पिछले चरणों में पहले से किए गए काम का पुन: उपयोग कर सकें?

हम मेमोइज़ेशन का उपयोग करके ऐसा कर सकते हैं।

हमारे महंगे गणना परिणामों को सहेजने के लिए हम एक कैश का उपयोग करते हैं। इस मामले में, एक सरणी पर्याप्त होगी।

उदाहरण:

 @cache = [0,1]
def fib(n)
  return @cache[n] if @cache[n]
  @cache[n] = fib(n-1) + fib(n-2)
end 

पहले हम जांचते हैं कि क्या परिणाम पहले से ही कैश में है, यदि है तो इसे वापस करें, अन्यथा हम गणना करते हैं और परिणाम सहेजते हैं।

यह बहुत तेजी से चलेगा और बहुत बड़ी फाइबोनैचि संख्याओं की गणना करने में सक्षम होगा।

रिकर्सन की सीमाएं

जैसा कि एक पाठक ने दयालुता से इंगित किया, रिकर्सिव समाधान SystemStackError: stack level too deep के साथ विफल हो सकता है बड़ी इनपुट संख्याओं के साथ (लगभग 7500, सटीक संख्या आपके सिस्टम पर निर्भर करती है)।

यदि आपको इससे भी बड़ी संख्या की गणना करने की आवश्यकता है तो आपको पुनरावृत्त समाधान का उपयोग करना होगा।

उदाहरण:

 memo = []
(0..n).each do |i|
  memo[i] = i < 2 ? i : memo[i-1] + memo[i-2]
end

निष्कर्ष

रिकर्सन बहुत अच्छा है लेकिन कभी-कभी इसे समझना कठिन हो सकता है। अब आपकी बारी है, अभ्यास से महारत आती है!

अगर आपको यह पसंद आया तो इस पोस्ट को शेयर करें और मेरे न्यूज़लेटर की सदस्यता लें 🙂


  1. रूबी मैट्रिक्स को समझना: परिभाषा, अनुप्रयोग और उन्हें कैसे बनाएं रूबी मैट्रिक्स को समझना: परिभाषा, अनुप्रयोग और उन्हें कैसे बनाएं

    मैट्रिक्स एक 2D (2-डायमेंशनल) ऐरे है जिसका उपयोग स्प्रेडशीट जैसे डेटा को स्टोर और काम करने के लिए किया जा सकता है। इनका उपयोग किया जा सकता है: टेबल गेम में बोर्ड को दर्शाना (शतरंज, चेकर्स, आदि) आंकड़े और डेटा विश्लेषण प्लॉट्स और ग्राफ़ उत्पन्न करना क्योंकि यह एक शक्तिशाली डेटा संरचना है इसलिए इसका

  1. Ruby में Alias कीवर्ड का उपयोग करके मेथड एलियास बनाना Ruby में Alias कीवर्ड का उपयोग करके मेथड एलियास बनाना

    Ruby में किसी मेथड को वैकल्पिक नाम देने के दो तरीके हैं: alias (कीवर्ड) alias_method चूंकि ये दोनों थोड़े अलग तरीके से एक ही काम करते हैं, इसलिए यह विषय भ्रमित करने वाला हो सकता है। यह छवि अंतरों का सारांश है: आइए इन अंतरों को विस्तार से समझते हैं ताकि आपको ठोस समझ मिल सके! alias कीवर्ड पहला है a

  1. रूबी स्ट्रक्ट्स और OpenStruct में महारत: कुशल वैल्यू ऑब्जेक्ट्स रूबी स्ट्रक्ट्स और OpenStruct में महारत: कुशल वैल्यू ऑब्जेक्ट्स

    रूबी में स्ट्रक्ट क्या है? एक स्ट्रक्ट एक बिल्ट-इन रूबी क्लास है, इसका उपयोग वैल्यू ऑब्जेक्ट्स उत्पन्न करने वाली नई क्लासेस बनाने के लिए किया जाता है। एक वैल्यू ऑब्जेक्ट संबंधित विशेषताओं को एक साथ संग्रहीत करने के लिए उपयोग किया जाता है। यहां एक उदाहरण है: दो निर्देशांकों (x और y) के साथ एक Point।