首先,这是一个家庭作业问题,所以只是寻找指导而不是答案。
编写一个名为(循环ALIST N)的函数,它接受一个元素列表ALIST和一个整数N.该函数返回一个包含N个元素重复的列表。如果N为非正数,则此函数返回空列表。
我会诚实地说,我不确定如何开始解决这个问题。我一直在考虑写一个辅助函数,然后使用cons调用这个n次,但只是看看我是否在这里正确的轨道。
答案 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
重置为n
,cdr
c
为零,默认情况保持{ {1}}同时将lst
的第一个元素c
和cons
减少到lst
。这是O(n)解决方案。