2015-11-18 9 views
6

कृपया निम्नलिखित कोड में रिकर्सन स्टेटमेंट के काम को समझाएं।जावा में रिकर्सन यह कैसे काम करता है?

int factR(int n) { 
    int result; 

    if(n==1) return 1; 

    result = factR(n-1) * n; 
    return result; 
} 

मेरे समझ है कि:

ऊपर बयान factR(n-1) विधि अंत तक ही कॉल में। मान लीजिए कि हम 6 का फैक्टोरियल प्राप्त करना चाहते हैं, जिसे इस विधि को तर्क के रूप में भेजा जाएगा। इसे n पैरामीटर के रूप में प्राप्त किया जाएगा, और n का मान चेक किया जाएगा; यदि यह 1 है तो 1 वापस कर दिया जाएगा। लेकिन अगर यह 1 नहीं है, जैसा कि हमारे मामले में 6 है, तो रिकर्सेशन स्टेटमेंट चलाएगा।

अब मुझे जिस समस्या का सामना करना पड़ता है वह यह है कि पहली बार n-1 5 हो जाता है और एन द्वारा गुणा किया जाता है, जिसमें मूल्य 6 होता है, तो यह 30 हो जाता है। अब वह 30 कहाँ होगा?

फिर विधि स्वयं को कॉल करेगी और इस बार n-1 4 हो जाता है और फिर यह n के साथ गुणा करता है, जिसमें "6" मान 4 * 6 = 24 मानता है जो मुझे लगता है कि गलत है। क्योंकि अगर हम इस तरह से जाते हैं तो अगली कॉल प्रक्रिया में कुछ ऐसा होगा, n-1 3 * एन बन जाएगा जो IF समान मान रखता है यानी 6 तो यह 3 * 6 = 18 बन जाएगा। फिर अगला कॉल होता है और n-1 यदि हम गुणा करते हैं और मानते हैं कि n मान 6 है तो 2 * 6 = 12, और अंतिम कॉल n-1 = 1 * n = 6. मेरा बिंदु यह है कि यह स्पष्ट है कि n-1 मान n-1 यानी 6-1 कम करेगा = 5 फिर 5-1 = 4 फिर 4-1 = 3 फिर 3-1 = 2 और 2-1 = 1। लेकिन सवाल यह है कि n का मूल्य क्या होगा जब विधि स्वयं कॉल होने पर हर बार गुणा किया जाएगा?

यदि आप कहते हैं कि जब पहली गुणा होती है यानी "एन -1" 5 हो जाती है तो 6 = 30 से गुणा हो जाती है और 30 को "एन" पर संग्रहीत किया जाता है, फिर अगली कॉल में 5-1 = 4 * 30 = 120 , फिर 4-1 = 3 * 120 = 360, फिर 3-1 = 2 * 360 = 720, और आखिरी 1 * 720 = 720 पर, जावा परिणामस्वरूप मान को वैरिएबल n में वापस करने का निर्धारण कैसे करता है?

मैं क्या चर result का मूल्य हर बार विधि इस तरह से ही कहते हैं, इस तरह है की जाँच करने के एक और बयान देते हैं:

int factR(int n) { 
    int result; 

    if(n==1) return 1; 

    result = factR(n-1)*n ; 
    System.out.println(result); 
    return result; 
} 

तो मैं मिलता है इस उत्पादन:

2 
6 
24 
120 
720 
Factorial of 6 is 720 

मुझे समझ में नहीं आता कि यह अपनी पहली कॉल में 2 कैसे उत्पन्न करता है। मूल्य 2 और फिर 6, 24, 120 और 720 कहां से आते हैं? मुझे लगता है कि मैं कोड के काम में गंभीर रूप से फंस गया हूँ।

+4

क्या आपने कोड डीबग करने का प्रयास किया था? – TheLostMind

+0

आप गलत तरीके से हैं। आपके मामले में इसे पहले '30' नहीं मिलेगा। यह '1 * 2' के साथ शुरू होगा -> परिणाम को कॉलर मेथोट' * 3' -> को कॉलर विधि '* 4' पर परिणाम पास करें। रिकर्सन कॉल की प्रत्येक कॉल स्टैक पर डाल दी जाती है, जो शीर्ष (अंतिम कॉल) से नीचे तक पहुंच जाती है (पहली कॉल) जब वह उस बिंदु तक पहुंच जाती है जहां यह कोई और रिकर्सन नहीं करता है। – SomeJavaGuy

+0

2 पहला कॉल नहीं है, दूसरा है, यह सिर्फ इतना है कि आपका पहला कॉल प्रिंटल – valepu

उत्तर

-1

विधि वास्तव में n के भाज्य खोजने के लिए इस तरह संरचित किया जाना चाहिए: एक पुनरावर्ती समारोह के अंदर नया चर का दृष्टांत है क्योंकि वे 'मेरी राय में

int factorial(int n) 
{ 
    if (n == 1) 
     return 1; 

    return n * factorial(n - 1); 
} 

यह एक बहुत अच्छा विचार नहीं है स्कोप के कारण बस प्रत्येक कॉल के साथ रीसेट किया जाएगा।

+0

यह कम तरीके से अपनी विधि के समान ही कर रहा है, बस वह प्रिंट स्टेटमेंट – SomeJavaGuy

+0

@ केविन एशे हाँ, मैं अपने कोड को डीबग करने में सक्षम हूं। पता है, मैं व्यक्तिगत रूप से वेरिएबल को तुरंत चालू करने के लिए खराब अभ्यास ढूंढता हूं जो अंततः रिकर्सन के कारण गुंजाइश से बाहर हो जाएगा; अधिक भ्रम जोड़ता है। –

+0

मुकेश कुमार से उपर्युक्त उत्तर पढ़ने के बाद, वास्तव में –

1

आप यहां क्या खो सकते हैं यह है कि n आपके फ़ंक्शन के लिए एक परिवर्तनीय स्थानीय है। इसका मतलब है कि आपके फ़ंक्शन के लिए प्रत्येक कॉल (इसे रिकर्सन के माध्यम से या नहीं) एक नया चर n प्राप्त करता है, जिसमें उस फ़ंक्शन का पैरामीटर होता है। चूंकि यह एक मान प्रकार है, इसकी प्रतिलिपि बनाई गई है और मूल मूल्य का संदर्भ नहीं है। इसलिए एक कॉल में इसमें कोई भी बदलाव अन्य (रिकर्सिव) कॉलों में चर को प्रभावित नहीं करता है।

नतीजतन आपके फ़ंक्शन को 6 की एक प्रति प्राप्त होती है और यह आपके फ़ंक्शन की अगली कॉल पर प्रतिलिपि के रूप में 1 द्वारा कम हो जाती है। उस कॉल को 6-1=5 की "प्रतिलिपि" मिलती है और इसे फिर से कम कर देती है - और इसी तरह। जब यह 1 तक पहुंचता है तो यह 1 भी देता है। फिर यह कॉल स्टैक के माध्यम से फिर से अपना रास्ता काम करता है और इस कॉल में स्थानीय चर के साथ अंतिम कॉल के परिणाम को गुणा करता है। तो 12 के साथ गुणा हो जाता है और वापस आ जाता है। यह परिणाम और इसी तरह से गुणा हो जाता है। अंत में आप फैक्टोरियल के साथ खत्म हो जाते हैं।

7

फ़ंक्शन समाप्त होने तक फ़ंक्शन फैलता है (n == 1)। तो n = 6 मान लीजिए, तो हमारे पास factR(n-1) * n = factR(5) * 6 है, लेकिन factR(5) क्या है? वैसे यह सिर्फ factR(4) * 5 है, और इसलिए हम देखते हैं कि factR(5) * 6 = (factR(4) * 5) * 6। अब ध्यान दें कि factR(1) = 1, और हम

factR(6) = factR(5) * 6 
     = (factR(4) * 5) * 6 
     = ((factR(3) * 4) * 5) * 6 
     = (((factR(2) * 3) * 4) * 5) * 6 
     = ((((factR(1) * 2) * 3) * 4) * 5) * 6 
     = ((((1 * 2) * 3) * 4) * 5) * 6 
     = (((2 * 3) * 4) * 5) * 6 
     = ((6 * 4) * 5) * 6 
     = (24 * 5) * 6 
     = 120 * 6 
     = 720 
0

जावा में मिलता है, हम कुछ एक ढेर कहा जाता है।

हर बार एक विधि को किसी अन्य विधि द्वारा बुलाया जाता है, यह ढेर में जोड़ा जाता है।

________ 
|factR(1)| = <prints nothing> 
________ 
|factR(2)| = 2 
________ 
|factR(3)| = 6 
________ 
|factR(4)| = 24 
________ 
|factR(5)| = 120 
________ 
|factR(6)| = 720 

यह मूलतः इसका मतलब है कि factR(6) विधि को पूरा करने के लिए, factR(5), पूरा factR(5) को पूरा करने के लिए, factR(4) को पूरा करने और इतने पर करना चाहिए।

factR(6) में आप factR(5) पर कॉल करते हैं और फिर इसे पूरा करने के लिए प्रतीक्षा करते हैं, क्योंकि परिणाम इस पर निर्भर करता है।

लेकिन, factR(5) में, आप भी एक रिकर्सिव कॉल करते हैं और आपको प्रतीक्षा करनी होगी।

और इसी तरह, जब तक हम सीमा factR(1), जो सिर्फ वापस आ जाएगी 1.

factR(1) पूरा साथ मारा, factR(2) तो परिणाम मुद्रित करें और अपनी मूल विधि के लिए परिणाम लौटने के लिए, और इतने पर कर सकते हैं, जब तक factR(6) प्रिंट करता है और इसके परिणाम लौटाता है

+0

bruno_cw प्रश्न का उत्तर नहीं देता है, आपका उत्तर वास्तव में समझना बहुत आसान था, और स्पष्ट रूप से यह स्पष्ट शब्द के रूप में स्पष्ट है :-), मुझे उम्मीद है कि ज्ञान साझा किया जाएगा आपके द्वारा इस तरह का एक सुंदर तरीका, धन्यवाद –

+0

वाह बहुत बहुत धन्यवाद! :) –

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