(define a (make-vector 1001)) (define b (make-vector 1001)) (define tmp 0) (define fibonacci (lambda () (let ((n (read))) (if (not (eof-object? n)) (begin (vector-fill! a 0) (vector-fill! b 0) (vector-set! a 0 1) (vector-set! b 0 1) (cond ((= n 0) (begin (display 0) (newline) (fibonacci))) ((= n 1) (begin (display 1) (newline) (fibonacci))) ((= n 2) (begin (display 1) (newline) (fibonacci))) (else (do ((i 3 (+ i 1))) ((> i n) (begin (print-fib b) (newline) (fibonacci))) (big-add a b) (set! tmp a) (set! a b) (set! b tmp))))))))) (define print-fib (lambda (fib) (set! tmp #f) (do ((i 1000 (- i 1))) ((equal? tmp #t)) (if (not (= (vector-ref fib i) 0)) (begin (set! tmp #t) (do ((k i (- k 1))) ((< k 0)) (display (vector-ref fib k)))) (set! tmp #f))))) (define big-add (lambda (x y) (do ((i 0 (+ i 1))) ((>= i 1000)) (set! tmp (+ (vector-ref x i) (vector-ref y i))) (if (> tmp 9) (begin (set! tmp (- tmp 10)) (vector-set! x i tmp) (vector-set! x (+ i 1) (+ 1 (vector-ref x (+ i 1))))) (vector-set! x i tmp))))) (fibonacci)
假定機器是32位,在C語言上,int類型所佔用的內存大小爲4byte,那麼,能夠表示的最大數字爲2147483647,只有十位數。題目要求的是,在1000位之內,顯然用int不可行。再lisp裏面,它是默認進行大數轉換的,可是這個題目考察的是大數加法,因此咱們就模擬小學剛學習加法的時候用的豎式相加的方法進行計算。數組
big-add
是我用來實現豎式計算的一個函數。兩個全局變量a和b分別用來保存豎式相機的得數。具體的計算方法和豎式相加是同樣的,若是兩個數相加得數大於9,那麼,向前一位加1,自身獲得的和減去10。
print-fib
用於打印最後的斐波那契數,最終獲得的是一個保存了斐波那契數的數組。例如,從第1個數組元素到最後一個數組元素依次顯示爲000000012345678...00,那麼,咱們應該打印出來的是12345678...00,而不是把前面的0都打印出來。咱們只要判斷數組從哪一位開始是非零,把剩餘的數組元素依次打印出來便可。
fibonacci
是計算斐波那契數的函數,把a和b相加 獲得下一個斐波那契數。函數
最後,在個人機器上,能夠正確的跑出全部要求內的斐波那契數,我用的是DrRacket,問題是OJ上一直跑不過,每次放上面都是runtimeerror。我在虛擬機上,在guile1.8的環境下跑這個程序,一樣能夠正確運行。最後,這個題目,我用了C++,一樣的思路,依次經過了。很是遺憾。學習