Szukaj…


Uwagi

Lisp jest często wykorzystywany w kontekstach edukacyjnych, gdzie uczniowie uczą się rozumieć i wdrażać algorytmy rekurencyjne.

W kodzie produkcyjnym napisanym we wspólnym Lisp lub w kodzie przenośnym występuje kilka problemów z rekurencją: nie korzystają one z funkcji specyficznych dla implementacji, takich jak optymalizacja wywołania ogona , co często powoduje konieczność całkowitego uniknięcia rekurencji. W takich przypadkach wdrożenia:

  • Zwykle mają limit głębokości rekurencji ze względu na ograniczenia wielkości stosów. Dlatego algorytmy rekurencyjne będą działać tylko dla danych o ograniczonym rozmiarze.
  • Nie zawsze zapewniają optymalizację wezwań ogonowych, szczególnie w połączeniu z operacjami o dynamicznym zasięgu.
  • Zapewnij optymalizację wywołań ogonowych tylko na określonych poziomach optymalizacji.
  • Zwykle nie zapewniają optymalizacji ogona .
  • Zwykle nie zapewniają optymalizacji ogonów na niektórych platformach. Na przykład implementacje w JVM mogą tego nie robić, ponieważ sama JVM nie obsługuje optymalizacji wywołania ogona .

Zastąpienie wezwań ogonowych skokami zwykle utrudnia debugowanie; Dodanie skoków spowoduje, że ramki stosu staną się niedostępne w debuggerze. Jako alternatywy Common Lisp zapewnia:

  • Konstrukcje DOTIMES , takie jak DO , DOTIMES , LOOP i inne
  • Funkcje wyższego rzędu, takie jak MAP , REDUCE i inne
  • Różne struktury kontrolne, w tym niskiego poziomu, go to

Szablon rekurencyjny 2 warunek

 (defun fn (x)
      (cond (test-condition1 the-value1)
            (test-condition2 the-value2)
            ...
            ...
            ...
            (t (fn reduced-argument-x))))


 CL-USER 2788 > (defun my-fib (n)
                 (cond ((= n 1) 1)
                       ((= n 2) 1)
                       (t (+
                           (my-fib (- n 1))
                           (my-fib (- n 2))))))
MY-FIB

CL-USER 2789 > (my-fib 1)
1

CL-USER 2790 > (my-fib 2)
1

CL-USER 2791 > (my-fib 3)
2

CL-USER 2792 > (my-fib 4)
3

CL-USER 2793 > (my-fib 5)
5

CL-USER 2794 > (my-fib 6)
8

CL-USER 2795 > (my-fib 7)
13

Szablon rekurencyjny 1 pojedynczy warunek pojedynczy ogon rekurencyjny

(defun fn (x)
  (cond (test-condition the-value)
        (t (fn reduced-argument-x))))

Oblicz n-tą liczbę Fibonacciego

;;Find the nth Fibonacci number for any n > 0.
;; Precondition: n > 0, n is an integer. Behavior undefined otherwise.
(defun fibonacci (n)
    (cond
        (                                     ;; Base case.
             ;; The first two Fibonacci numbers (indices 1 and 2) are 1 by definition.
            (<= n 2)                          ;; If n <= 2
            1                                 ;; then return 1.
        )
        (t                                    ;; else
            (+                                ;; return the sum of
                                              ;; the results of calling 
                (fibonacci (- n 1))           ;; fibonacci(n-1) and
                (fibonacci (- n 2))           ;; fibonacci(n-2).
                                              ;; This is the recursive case.
            )
        )
    )
)

Rekurencyjnie drukuj elementy listy

;;Recursively print the elements of a list
(defun print-list (elements)
    (cond
        ((null elements) '()) ;; Base case: There are no elements that have yet to be printed. Don't do anything and return a null list.
        (t
            ;; Recursive case
            ;; Print the next element.
            (write-line (write-to-string (car elements)))
            ;; Recurse on the rest of the list.
            (print-list (cdr elements))
        )
    )
)

Aby to przetestować, uruchom:

(setq test-list '(1 2 3 4))
(print-list test-list)

Wynik będzie:

1
2
3
4

Oblicz silnię liczby całkowitej

Jednym łatwym algorytmem, który można zaimplementować jako funkcję rekurencyjną, jest silnia.

;;Compute the factorial for any n >= 0. Precondition: n >= 0, n is an integer.
(defun factorial (n)
    (cond
        ((= n 0) 1) ;; Special case, 0! = 1
        ((= n 1) 1) ;; Base case, 1! = 1
        (t
            ;; Recursive case
            ;; Multiply n by the factorial of n - 1.
            (* n (factorial (- n 1)))
        )
    )
)


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow