我可以在球拍中打印列表的替代元素吗?

时间:2015-09-14 23:55:40

标签: function recursion racket

例如,如果我创建一个名为odd-places的函数,它应该按如下方式工作,

(odd-places  '(p q r s t 1 2)) =  (p r t 2) 

可以使用递归来完成吗? 谢谢。

5 个答案:

答案 0 :(得分:1)

类似Scheme的语言中的基本列表尾递归模式是:

  • 检查停止条件,此处null?测试停止递归
  • 完成剩下的工作,在这种情况下为条件添加一个分支来过滤奇数索引,因此i必须是偶数(因为它从1开始而不是0)

应用这个给我们

(define (odd-places lst)
  (define (remove-rec lst i)
    (cond ((null? lst) '())
          ((odd? i) (cons (car lst) (remove-rec (cdr lst) (+ i 1))))
          (else (remove-rec (cdr lst) (+ i 1))))) // i is even, skip this element!
  (remove-rec lst 1))

答案 1 :(得分:1)

这是一种递归方法,通过使用两个相互递归函数来解决任务。在这种方法中,不需要辅助变量,检查奇数或均匀度。

(define (odd-places lst)
  (define (get lst)
    (if (null? lst)
        '()
        (cons (car lst) (dont-get (cdr lst)))))
  (define (dont-get lst)
    (if (null? lst)
        '()
        (get (cdr lst))))
  (get lst))

第一个函数get列表中的第一个项目,并将第二个函数的结果应用于列表的其余部分,dont-get列表的第一个元素立即返回第一个函数应用于列表的其余部分。

这个版本在堆栈使用的空间和执行时间方面比HyperZ的答案中的经典递归更有效。

最后,考虑到前面的解决方案是如何工作的,我们可以解决在单个递归调用中“折叠”两个内部函数的问题,而不需要辅助函数或变量:

(define (odd-places lst)
  (cond ((null? lst) '())
        ((null? (cdr lst)) (list (car lst)))
        (else (cons (car lst) (odd-places (cddr lst))))))

答案 2 :(得分:1)

您的示例实际上是显示列表中的 even 元素,因为第0个(偶数)元素是p。这就是为什么下面的解决方案使用even?

其他答案都有针对性的递归解决方案,但您没有说明为什么需要它递归。如果您只是想要一种简洁的方法来获得替代品,那么“理解”也可以起作用:

(for/list ([i (length lst)] #:when (even? i))
  (list-ref lst i))

More info on for/list here.

答案 3 :(得分:1)

比以前的答案更短的版本:

 
(define (odd-places lst)
  (if (or (null? lst) (null? (cdr lst)))
          lst
          (cons (car lst) (odd-places (cddr lst)))))

测试:

> (odd-places  '(p q r s t 1 2))
'(p r t 2)

答案 4 :(得分:0)

一个小小的附录:使用此功能,您可以选择列表中应跳过的项目,然后再将其包含在结果列表中。

(define (nth-places n lst [i 0])
  (cond
    [(null? lst) null]
    [(= i 0) (cons (car lst)
                   (nth-places n (cdr lst) (+ i 1)))]
    [(= i n) (nth-places n (cdr lst) 0)]
    [else (nth-places n (cdr lst) (+ i 1))]))

i中的[i 0]是一个可选参数,您不必在调用函数时指定它,因为在这种情况下它具有设置的起始值0。这里i用作累加器索引,我们从零开始计数而不是一个。

n定义只应选择所有第n个元素来构建新列表,我们再次开始索引为0。

如果你想生产像这里的交替元素

(odd-places  '(p q r s t 1 2)) =  (p r t 2)

你会打电话给

(nth-places 1 '(p q r s t 1 2))

对于每个第三个元素集n到2,依此类推。