Lisp學習筆記(二)

2021-06-28 01:13:58 字數 1694 閱讀 5034

對於階乘運算n!,採用遞迴形式編寫是非常容易理解的:

(define (factorial n)

(if (= n 1) 1

(* n (factorial (- n 1))

))

計算6!,其執行過程是這樣的:

(factorial 6)

(* 6 (factorial 5))

(* 6 (* 5 (factorial 4)))

(* 6 (* 5 (* 4 (factorial 3))))

(* 6 (* 5 (* 4 (* 3 (factorial 2)))))

(* 6 (* 5 (* 4 (* 3 (* 2 (factorial 1))))))

(* 6 (* 5 (* 4 (* 3 (* 2 1)))))

(* 6 (* 5 (* 4 (* 3 2))))

(* 6 (* 5 (* 4 6))

(* 6 (* 5 24)

(* 6 120)

720

可以看出,在計算n!過程中,推遲執行的乘法鏈條的長度,也就是為儲存其軌跡需要儲存的資料量,這個長度隨著n值而線性增長。

下面我們採用迭代形式來重構這個過程:

(define (newfac n)

(define (ite***c result counter)

(if (= counter n) (* n result)

(ite***c (* result counter) (+ counter 1))))

(ite***c 1 1)

)

這裡我們定義了兩個過程,ite***c是定義在newfac內部,只能被newfac呼叫。同樣,我們用來計算6!時,它的計算過程是這樣的:

(newfac 6)

(ite***c 1 1)

(ite***c 1 2)

(ite***c 2 3)

(ite***c 6 4)

(ite***c 24 5)

(ite***c 120 6)

720

迭代過程中,沒有任何儲存資料量的增長,對於任何乙個n,在計算過程中的每一步,我們需要儲存的就是result和counter。用乙個變數(eg. result)傳遞迭代過程中狀態的變化,這是迭代過程的核心!

下面給出乙個o(logn)複雜度的冪運算的迭代過程:

(define (newexp b n)

(define (even? n)

(= (remainder n 2) 0)

) (define (iterexp a k result)

(cond ((= k 1) result)

((even? k) (iterexp (* a a) (/ k 2) (* result result)))

(else (* (iterexp a (- k 1) result) a))

)) (iterexp b n b)

)

(even? n)用來判斷n是基數還是偶數,計算b^n時,我們採用的是這樣一種方法:

b^n = (b^2)^(n/2) (n是偶數時),b^n = b^(n-1)*b(n為奇數),result用來儲存計算結果,a用來儲存基數的變化。

Lisp 學習日誌

從噹噹買到了 實用common lisp教程 冰河譯 終於有本 新 的lisp書了。準備把學習過程中比較惱人的問題記在這裡。sbcl clisp都只有x86版,看著clozure cl 1.7 有win64版,因為用的win64,就選了ccl。嘗試 format nil r 999999999999...

ACSL競賽筆記 Lisp

acsl競賽考到的lisp控制符 1 car 保留list中第一部分 可能為乙個元素,也可能為乙個子list 2 cdr 去掉list中第一部分 3 reverse 把list中各個部分倒序輸出 4 setq 賦值運算子,把乙個變數賦值為乙個list 例題 setq x a b c d e b c ...

lisp學習總結(一)

lisp太簡單 lisp核心太簡單了只有幾個簡單的邏輯定理,簡單到你會認為他啥事都做不了。lisp語法太簡單了,只有符號,引數,以及括號,組成一種萬能的表示式。由於上述lisp的簡單,所以對於初學者來講,他太難了,因為要做事情,上面這些簡單的規則根本不足以讓初學者構造高樓大廈。所以構造高樓大廈的話學...