【问题标题】:trying to write a function that returns every third element in a list in racket language尝试编写一个函数,以球拍语言返回列表中的每三个元素
【发布时间】:2018-12-16 02:55:04
【问题描述】:

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

【问题讨论】:

  • 抱歉,代码中的skipper应该是递归函数调用名称,我在发布代码时更改了函数顶部的函数名称,并在考虑正文之前过早地点击了发布问题编码。我的道歉。在我的实际代码中,函数名和函数体中的递归名是一样的。这不是错误的问题。
  • triple 应该拿一个清单吧?是来自[Listof X] -> [Listof X] 的函数吗?
  • 假设这是真的,在 triple 的正文中,lst 的类型为 [Listof X],(cdr lst)、(cdr (cdr lst)) 和 (cdr (cdr (cdr lst))) 也是如此,因为如果你给 @ 987654330@ 一个列表,它为其余部分生成另一个列表。但是,你也有一个car,我不知道为什么。因为如果你给car 一个平面列表,你将不会得到一个列表。 (car (cdr (cdr (cdr lst)))) 将不会成为[Listof X]。
  • @teaNcode 如果您发布的问题有一些错误,您可以(并且应该!)编辑您的问题。

标签: racket


【解决方案1】:

问题只是cdddr 周围的car。

(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)

【讨论】:

  • @PetSerAl 谢谢!来自 common-lisp 我忘记了 Racket (cdr '()) 不起作用。修改后可以正常工作。
【解决方案2】:

问题是当lst 的元素少于3 个时,您不能调用(cdr (cdr (cdr 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 不必要地计算列表的长度

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-11
    相关资源
    最近更新 更多