试图编写一个返回列表中每三个元素的函数
包括球拍中的第一个元素。我现在得到的只是我的代码第一个爆炸:违反合同
预期:(和/ c列表?(不/ c为空?))
给出:4
(define l (list 1 2 3 4 5 6 7 8 9))
(define (skipper lst)
(if (null? lst)
'()
(cons (first lst)
(skipper (car (cdr (cdr (cdr lst))))))))
(skipper l)
答案 0 :(得分:0)
问题只是car
周围的cdddr
。
(define l (list 1 2 3 4 5 6 7 8 9))
(define (skipper lst)
(if (null? lst)
'()
(cons (first lst)
(skipper (if (< (length lst) 3)
'()
(cdddr lst))))))
(skipper l) ;; '(1 4 7)
通用解决方案
(define (my-cdr lst) ;; `cdr` behaving like in common-lisp: (cdr '()) -> '()
(cond ((null? lst) '())
(else (cdr lst))))
(define (multi-cdr lst k) ;; apply `my-cdr` k-times on `lst`
(cond ((zero? k) lst)
(else (multi-cdr (my-cdr lst) (- k 1)))))
(define (skipper lst k)
(if (null? lst)
'()
(cons (first lst)
(skipper (multi-cdr lst k) k))))
测试:
(skipper l 3) ;; '(1 4 7)
(skipper l 4) ;; '(1 5 9)
(skipper l 2) ;; '(1 3 5 7 9)
(skipper l 1) ;; '(1 2 3 4 5 6 7 8 9)
答案 1 :(得分:0)
问题是,当(cdr (cdr (cdr lst)))
的元素少于3个时,您将无法调用lst
。
您用球拍标记了这个,所以我将向您展示使用match
的解决方案
(define (skipper l)
(match l
;; some element and at least 3 more
((list a rest ..3)
(cons a (skipper (cddr rest))))
;; at least one element
((cons a _)
(list a))
;; otherwise
(else
empty)))
(skipper '())
;; '()
(skipper '(0))
;; '(0)
(skipper '(0 1 2 3 4 5 6 7))
;; '(0 3 6)
(skipper '(0 1 2 3 4 5 6 7 8 9))
;; '(0 3 6 9)
此解决方案不使用length
来不必要地计算列表长度