2011-09-30 6 views
13

मैं निम्नलिखित 2 कार्यों है कि मैं एक में गठबंधन करना चाहते हैं: मैं बस एक समारोह करना चाहते हैंrecursing

(defun fib (n) 
    (if (= n 0) 0 (fib-r n 0 1))) 

(defun fib-r (n a b) 
    (if (= n 1) b (fib-r (- n 1) b (+ a b)))) 

, इसलिए मैं कुछ इस तरह की कोशिश की:

(defun fib (n) 
    (let ((f0 (lambda (n) (if (= n 0) 0 (funcall f1 n 0 1)))) 
     (f1 (lambda (a b n) (if (= n 1) b (funcall f1 (- n 1) b (+ a b)))))) 
    (funcall f0 n))) 

हालांकि यह काम नहीं कर रहा है। सटीक त्रुटि *** - IF: variable F1 has no value मैं एक शुरुआतकर्ता हूं जहां तक ​​LISP जाता है, इसलिए मैं निम्नलिखित प्रश्न के स्पष्ट उत्तर की सराहना करता हूं: आप लिस्प में एक रिकर्सिव लैम्ब्डा फ़ंक्शन कैसे लिखते हैं?

धन्यवाद।

उत्तर

15

LET अभिव्यक्तियों का मूल्यांकन करने के लिए एक ही संलग्न वातावरण का उपयोग करके वैचारिक रूप से एक ही समय में चर को बांधता है। बजाय LABELS का उपयोग करें, वह भी प्रतीकों f0 और f1 समारोह नाम स्थान में बांधता है:

(defun fib (n) 
    (labels ((f0 (n) (if (= n 0) 0 (f1 n 0 1))) 
      (f1 (a b n) (if (= n 1) b (f1 (- n 1) b (+ a b))))) 
    (f0 n))) 
+0

धन्यवाद, यह काम करता है। –

+1

http://stackoverflow.com/suggested-edits/113745 – thirtydot

3

आप कुछ इस तरह के रूप में अच्छी तरह से

(defun fib-r (n &optional (a 0) (b 1)) 
    (cond 
    ((= n 0) 0) 
    ((= n 1) b) 
    (T (fib-r (- n 1) b (+ a b))))) 

पेशेवरों कोशिश कर सकते हैं: आप एक आवरण का निर्माण करने की जरूरत नहीं है समारोह। कंड कन्स्ट्रक्शन if-then-elseif परिदृश्यों का ख्याल रखता है। ए और बी के लिए तो उपयोगकर्ता की आपूर्ति मूल्यों, और अगर ये मान नहीं 0 और 1 हैं, तो आप अभ्यस्त सही जवाब

3

आप ग्राहम alambda उपयोग कर सकते हैं के लिए एक विकल्प के रूप में मिलता है: आप के रूप में (fib-r 10) => 55

विपक्ष आरईपीएल पर इस फोन लेबल:

(defun fib (n) 
    (funcall (alambda (n a b) 
      (cond ((= n 0) 0) 
        ((= n 1) b) 
        (t (self (- n 1) b (+ a b))))) 
      n 0 1)) 

या ... आप इस समस्या पर थोड़ा अलग दिखाई दे सकता है: Norvig उपयोग के defun-memo मैक्रो (स्वचालित Memoization), और मिथ्या के एक गैर पूंछ पुनरावर्ती संस्करण, एक मिथ्या समारोह है कि नहीं करता है परिभाषित करने के लिए एक सहायक समारोह की भी आवश्यकता नहीं है, और अधिक सीधे फाइब सेक के गणितीय विवरण व्यक्त करता है एनसी, और (मुझे लगता है) पूंछ रिकर्सिव संस्करण के रूप में कम से कम कुशल है, और कई कॉल के बाद, पूंछ-रिकर्सिव संस्करण से भी अधिक कुशल हो जाता है।

(defun-memo fib (n) 
    (cond ((= n 0) 0) 
     ((= n 1) 1) 
     (t (+ (fib (- n 1)) 
       (fib (- n 2))))))