Scheme - 返回所述列表的N个重复列表

时间:2018-02-07 20:45:26

标签: scheme racket

首先,这是一个家庭作业问题,所以只是寻找指导而不是答案。

编写一个名为(循环ALIST N)的函数,它接受一个元素列表ALIST和一个整数N.该函数返回一个包含N个元素重复的列表。如果N为非正数,则此函数返回空列表。

我会诚实地说,我不确定如何开始解决这个问题。我一直在考虑写一个辅助函数,然后使用cons调用这个n次,但只是看看我是否在这里正确的轨道。

2 个答案:

答案 0 :(得分:0)

解决递归问题的一种常见方法是在最后开始考虑它。换句话说,你应该在什么条件下停下来? - 你什么时候做的?如果你可以写下这个基础案例,那么你只需要问,当我离停止一步时我该怎么办?这是递归步骤,对于相对简单的递归问题,你可以完成,因为整个问题是"继续"做同样的事情或者"停止。"

了解基本情况通常会告诉您可能需要携带哪些额外信息(如果有的话)。

对于支持尾部调用优化的方案和球拍,最终可能会出现不同类型的递归。例如:

(define (normal-factorial n)
  (if (zero? n)
      1
      (* n (normal-factorial (- n 1)))))

(define (tail-factorial n)
  (letrec ((tf (lambda (product index)
                 (if (zero? index)
                     product
                     (tf (* product index) (- index 1))))))
    (tf n (- n 1))))

在第一种情况下,我们建立一个产品而不会倍增直到最后,而在第二种情况下,我们会尽快繁殖并随时携带这个临时产品。

并非所有问题都容易导致一种递归或另一种递归。

答案 1 :(得分:0)

您可以制定不同的策略。最简单的可能不是最有效的,而是产生更少代码的那个:

(require srfi/26) ; cut
(define (cycle lst n)
  (define dup-lst (map (cut make-list n <>) lst)) 
  (foldr append '() dup-lst))

这样做的是map创建一个列表列表,其中每个列表都是n元素。 foldr使用append将其展平。

通过更多动手,您可以提高效率。我想在累加器中滚动你自己的递归从头到尾的元素:

(define (cycle lst n)
  (let helper ((lst (reverse lst)) (c n) (acc '()))
    (cond ((null? lst) acc)
          ((<= c 0) (helper ...))
          (else (helper ...)))))

我遗漏了递归部分。这样做是空列表中的基本情况,重置重复,c重置为ncdr c为零,默认情况保持{ {1}}同时将lst的第一个元素ccons减少到lst。这是O(n)解决方案。