我正在嘗試創建一個列表,如(3 3 3 2 2 1)
。 我的代碼:如何創建一個列表(3 3 3 2 2 1)
(define Func
(lambda (n F)
(define L
(lambda (n)
(if (< n 0)
(list)
(cons n (L (- n 1))))))
(L n)))
我需要添加什麼,怎麼做呢? 謝謝
我正在嘗試創建一個列表,如(3 3 3 2 2 1)
。 我的代碼:如何創建一個列表(3 3 3 2 2 1)
(define Func
(lambda (n F)
(define L
(lambda (n)
(if (< n 0)
(list)
(cons n (L (- n 1))))))
(L n)))
我需要添加什麼,怎麼做呢? 謝謝
我會把它分解成三個功能。
(define (repeat e n) (if (= n 0) '() (cons e (repeat e (- n 1)))))
(define (count-down n) (if (= n 0) '() (cons n (count-down (- n 1)))))
(define (f n) (apply append (map (lambda (n) (repeat n n)) (count-down n))))
(f 3); => '(3 3 3 2 2 1)
壓扁了這一點,到一個單一的功能將需要是這樣的:
(define (g a b)
(if (= a 0) '()
(if (= b 0)
(g (- a 1) (- a 1))
(cons a (g a (- b 1))))))
(define (f n) (g n n))
(f 3) ;=> '(3 3 3 2 2 1)
(define (range n m)
(if (< n m)
(let up ((n n)) ; `n` shadowed in body of named let `up`
(if (= n m) (list n)
(cons n (up (+ n 1)))))
(let down ((n n))
(if (= n m) (list n)
(cons n (down (- n 1)))))))
(define (replicate n x)
(let rep ((m n)) ; Named let eliminating wrapper recursion
(if (= m 0) '() ; `replicate` partial function defined for
(cons x ; zero-inclusive natural numbers
(rep (- m 1))))))
(define (concat lst)
(if (null? lst) '()
(append (car lst)
(concat (cdr lst)))))
(display
(concat ; `(3 3 3 2 2 1)`
(map (lambda (x) (replicate x x)) ; `((3 3 3) (2 2) (1))`
(range 3 1)))) ; `(3 2 1)`
替代concat
:
(define (flatten lst)
(if (null? lst) '()
(let ((x (car lst))) ; Memoization of `(car lst)`
(if (list? x)
(append x (flatten (cdr lst)))
(cons x (flatten (cdr lst)))))))
(display
(flatten '(1 2 (3 (4 5) 6) ((7)) 8))) ; `(1 2 3 (4 5) 6 (7) 8)`
下面是一個尾遞歸版本。它做反向迭代!
(define (numbers from to)
(define step (if (< from to) -1 1))
(define final (+ from step))
(let loop ((to to) (down to) (acc '()))
(cond ((= final to) acc)
((zero? down)
(let ((n (+ to step)))
(loop n n acc)))
(else
(loop to (- down 1) (cons to acc))))))
(numbers 3 1)
; ==> (3 3 3 2 2 1)
要在標準方案這項工作,你可能需要將define
改變let*
因爲它肯定step
不可用的時候final
獲取評估。
我會用一個簡單的遞歸過程與build-list
(define (main n)
(if (= n 0)
empty
(append (build-list n (const n)) (main (sub1 n)))))
(main 3) ;; '(3 3 3 2 2 1)
(main 6) ;; '(6 6 6 6 6 6 5 5 5 5 5 4 4 4 4 3 3 3 2 2 1)
而且這裏有一個尾遞歸版本
(define (main n)
(let loop ((m n) (k identity))
(if (= m 0)
(k empty)
(loop (sub1 m) (λ (xs) (k (append (build-list m (const m)) xs)))))))
(main 3) ;; '(3 3 3 2 2 1)
(main 6) ;; '(6 6 6 6 6 6 5 5 5 5 5 4 4 4 4 3 3 3 2 2 1)
什麼是'F'呢? – Sylwester
只是一個提示,當你使用'(define(fname arg))'語法而不是'(define fname(lambda(arg))''' – Unlocked