尝试编写一个函数,该函数返回球拍语言中列表中的每三个元素

时间:2018-12-16 02:55:04

标签: racket

试图编写一个返回列表中每三个元素的函数    包括球拍中的第一个元素。我现在得到的只是我的代码第一个爆炸:违反合同
   预期:(和/ 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)

2 个答案:

答案 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来不必要地计算列表长度