2011-03-02 19 views
5

से समझाएं मुझे इस फ़ंक्शन के बाद कठिन समय हो रहा है। मुझे समझ नहीं आता कैसे चर start 16 को वापस reverts के बाद यह है जो 26 के एक मूल्य तक पहुँच जाता है से अधिक 24.इस जावास्क्रिप्ट फ़ंक्शन को Eloquent जावास्क्रिप्ट

function findSequence(goal) { 
    function find(start, history) { 
    if (start == goal) 
     return history; 
    else if (start > goal) 
     return null; 
    else 
     return find(start + 5, "(" + history + " + 5)") || 
      find(start * 3, "(" + history + " * 3)"); 
    } 
    return find(1, "1"); 
} 

print(findSequence(24)); 

ठीक है कि स्पष्ट हो सकता है, कुछ समय के लिए इस देखने के बाद, मैं कुछ प्रश्न हैं एक कुछ चीजें:

1) क्या यह कहने का एक सही बयान है कि प्रत्येक कॉल को खोजने के लिए यह अपने स्वयं के प्रारंभ मूल्य का ट्रैक रखता है? उदाहरण के लिए, जब (1) को कॉल किया जाता है, तो इसका प्रारंभ मूल्य 1 होता है, जब खोज (1 + 5) कहा जाता है, तो ढूंढें (1) का प्रारंभ मूल्य अभी भी एक है, लेकिन अब (1 + 5) ढूंढें यह 6 का अपना प्रारंभिक मूल्य है।

2) मुझे स्टैकट्रैक के बाद कठिन समय हो रहा है, भले ही मैं इसे मुद्रित करता हूं। यह कैसे मैं इसे देख रहा हूँ:

खोज (1) कहता है लगता है (1 + 5) शुरू // = 1

खोज (6) कॉल लगता है (6 + 5) = 6 शुरू //, पासेस

खोज (11) कॉल लगता है (11 + 5) शुरू // = 11, पासेस

खोज (16) कॉल लगता है (16 + 5) शुरू // = 16, पासेस

खोज (21) कॉल ढूंढें (21 + 5) // स्टार्ट = 21, विफलता

बेका खोज का उपयोग करें (21 + 5) शून्य लौटाता है, यह खोजने के लिए कोशिश करता है (21 * 3) जो शून्य भी देता है।

यह वह हिस्सा है जो मैं फंस जाता हूं, अगर दोनों पाते हैं (21 + 5) और पाते हैं (21 * 3) वापस लौटते हैं, तो यह पता लगाने के लिए कैसे पता चलता है (16 * 3)। ऐसा क्यों नहीं मिलता है (16 + 5) फिर से?

क्या ऐसा कुछ करने के लिए है जहां खोजने के लिए (21 + 5) और ढूंढें (21 * 3) को खोजने के लिए बुलाया गया था (16) और क्योंकि वे कॉलिंग फ़ंक्शन में शून्य हो गए, यह || बयान जो मिला था (16 * 3)।

+1

दो पाइप का अर्थ "या" नहीं है? आप एक चीज़ या दूसरी चीज़ कैसे वापस कर सकते हैं? – ScottC

+0

@ एसकॉटसी: जावास्क्रिप्ट में, "या" '|| || 'पहला आइटम देता है यदि यह सत्य-हैश है, या दूसरा आइटम यदि पहला आइटम झूठा-आश है (जिसमें शून्य शामिल है)। यह बूलियन का एक सामान्यीकरण है-या, और एक नल-कोलेसे ऑपरेटर के समान व्यवहार करता है। – Jimmy

+0

@ScottC: बूलियन स्थितियों के बारे में अपनी जावास्क्रिप्ट पुस्तक में अध्याय पढ़ें। यह 'var x = y || जैसा ही है z; वापसी x; '। –

उत्तर

2

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

जब खोज (21) कहा जाता है, यह शून्य देता है, क्योंकि खोज (26) और पाते हैं (63) वापसी अशक्त इसी तरह, खोज (16) और पाते हैं (11) वापसी अशक्त

जब खोज (6) कहा जाता है, यह कॉल (11) कहता है, जो शून्य देता है, इसलिए यह अगले (24) को कॉल करता है। इस कॉल के संदर्भ में , == 6 शुरू करते हैं, तो यह + 5 शुरुआत के साथ जारी है और शुरू * 3.

find(6): 
start = 6, history = (1 + 5) 
    find(6 + 5): 
    start = 11, history = ((1 + 5) + 5) 
     find(11 + 5): 
     start = 16, history = (((1 + 5) + 5) + 5) 
     ... continued etc... 

     find(11 * 3): 
     start = 33, history = (((1 + 5) + 5) * 3) 
     <end> 
    find(6 * 3): 
    start = 24, history = ((1 + 5) * 3) 
+0

मैं मानता हूं कि खोज के नए उदाहरणों में शुरुआत और इतिहास के नए उदाहरण हैं, शायद इसके बजाय चर से गुजरने ByVal जावास्क्रिप्ट ByRef पास करने का एक तरीका है ?? सी ++ की तरह? यदि यह वास्तव में – ScottC

+0

को पूरा करने का प्रयास कर रहा है, तो यह कहा गया है कि कहा गया कार्य सही है। Xaisoft बस लगता है कि खोजने का एक ही संदर्भ है (कई हैं)। तुलना करें "खोज के समानता का एक ही संदर्भ है, और इस प्रकार लक्ष्य के लिए एक मूल्य" (जो सत्य है) – Jimmy

2

आप यह देखते हुए कि प्रत्यावर्तन शाखाओं बाहर नहीं कर रहे हैं। ऐसा लगता है कि झटके ऊपर और नीचे शुरू हो जाते हैं, लेकिन आप बस एक रिकर्सन पेड़ के नीचे पहुंच रहे हैं और एक अलग से छोड़ रहे हैं।

कॉल के माध्यम से कार्य करना: प्रत्यावर्तन पेड़ में start की


वैल्यू (start+5/start*3 पर शाखाओं):

     1 
       6---------+----------3 
     11----+--18   8-----+----- 
    16-+-33 23-+--48 13-+--24 
    21-+-80 28+69  18+39 
26+63    23+90 
        28+69 

देखें कि किस प्रकार प्रत्येक शाखा समाप्त होता है जब मूल्य बहुत अधिक हो जाता है, तो start का मान जो आप देखते हैं नीचे प्रसंस्करण के रूप में अगली शाखा में कूदता है। प्रसंस्करण बंद हो जाता है जब '24' पाया जाता है।


:

+0

यह प्रारंभ> लक्ष्य के दौरान एक गहराई से पहली बार रोक रहा है, इसलिए खोजने के पहले (26) होता है (24) होता है , जो Xaisoft के बारे में उलझन में है। – Jimmy

+0

@ जिमी: जब 'स्टार्ट> लक्ष्य' होता है तो यह रुकता नहीं है, यह 'start == target' के समय बंद हो जाता है। जब 'प्रारंभ> लक्ष्य' वर्तमान पेड़ को छोड़ दिया जाता है, लेकिन अन्य अभी भी खोजे जाते हैं। –

+0

हां, सवाल में भ्रम इसलिए है क्योंकि वह सोचता है कि शुरुआत का केवल एक ही मूल्य है। – Jimmy

6

शायद आप पूरी तरह आश्वस्त नहीं हैं, लेकिन आप यह मिल गया (अस्वीकरण मैं पूरी तरह से सभी गणित की जाँच नहीं की है, लेकिन सिद्धांत ध्वनि होना चाहिए!)।

प्रश्न 1 के संबंध में, यह कहना सही है कि start मूल्य आंतरिक कॉल के साथ संरक्षित हैं। ऐसा लगता है कि प्रत्येक कॉल का अपना "संदर्भ" होता है - भले ही आप चर और तर्क मान संशोधित करते हैं, यह बाहरी फ़ंक्शन कॉल में नहीं ले जाता है। वह गुंजाइश है।

प्रश्न 2 शॉर्ट-सर्किट बूलियन मूल्यांकन से संबंधित प्रतीत होता है। व्यवहार वही है जो आपने वर्णित किया: एक बार || ऑपरेटर के बाईं ओर अभिव्यक्ति कुछ "सत्य" लौटाती है, दाईं ओर अभिव्यक्ति का मूल्यांकन नहीं किया जाएगा। और इसके विपरीत भी सत्य है: यदि बायां अभिव्यक्ति "झूठी" है, तो दुभाषिया सही अभिव्यक्ति का मूल्यांकन करने के लिए आगे बढ़ेगा। परिणामी मान पहला गैर-झूठा मूल्य होगा, या श्रृंखला में अंतिम मूल्य होगा।

तो मुझे लगता है कि आपको सबकुछ मिला है!


मैंने मूल स्क्रिप्ट को बदल दिया ताकि यह कॉल ट्रेस प्रिंट कर सके। इसे here में देखें।

यह एक आंशिक ट्रेस जहां start का मूल्य 16 "कमी" के बाद इसे आगे जाता है प्रकट होता है:

enter image description here

समारोह तो यह desists, आगे 16 शाखा के अंतर्गत एक छोटे से चला जाता है, ऊपरी कॉल पर वापस लौटना जहां start 11 है। फिर यह start के लिए 11 * 3 के मान का प्रयास करने के लिए आगे बढ़ता है, फिर यह फिर से समाप्त होता है, और इसी तरह।

+0

बहुत बढ़िया, मैं इसे हाथ से चल रहा हूं और शायद मेरा प्रश्न अपडेट करूँगा क्योंकि मुझे लगता है कि मुझे यह मिल रहा है, लेकिन अभी तक नहीं। – Xaisoft

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