我正在努力学习如何做到这一点,我知道它涉及到堆栈,但除非我看到一个功能在运行,否则我无法绕过它。我们已经给出了这个创建函数的例子,我需要一些帮助。这是:
;leafpile takes a list and returns the result of pushing all
;occurrences of the symbol 'leaf to the end of the list
> (leafpile '(rock grass leaf leaf acorn leaf))
(list 'rock 'grass 'acorn 'leaf 'leaf 'leaf)
我们可以使用辅助函数,但函数需要以最小化递归传递的方式编写
更新(以下是我到目前为止所得到的)
(define (leafpile/help ls pile)
(local
[
(define (helper 2ls leafpile)
(cond
[(empty? 2ls) (filter ls 'leaf)]
[(equal? (first 2ls) 'leaf)
(cons (first 2ls) (helper (rest 2ls) leafpile))]
[else (helper (rest 2ls) leafpile)]))]
(helper ls pile)))
好雪我有这个:
(define (helper lsh)
(cond
[(empty? lsh) '()]
[(not(equal? (first lsh) 'leaf))
(cons (first lsh) (helper (rest lsh)))]
[else (helper (rest lsh))]))
(define (count-leaf ls)
(cond
[(empty? ls) 0]
[(not (equal? 'leaf (first ls))) (count-leaf (rest ls))]
[else (add1 (count-leaf (rest ls)))]))
(define (leafpile ls)
(append (helper ls) (make-list (count-leaf ls) 'leaf)))
但我需要在一个简单的函数中使用最少的递归传递。
答案 0 :(得分:0)
以下是我提出的解决方案:
(define (leafpile lst)
(for/fold ([pile (filter (lambda (leaf?) (not (equal? leaf? 'leaf))) lst)])
([i (build-list (for/fold ([leaves 0])
([leaf? lst])
(if (equal? leaf? 'leaf)
(add1 leaves)
leaves)) values)])
(append pile '(leaf))))
工作原理:
主for/fold
循环遍历列表,其中包含叶子数量的长度,“集合值”是lst
中不是符号{{{}的所有元素的列表。 1}}(由'leaf
实现)
样本输入/输出:
> (叶堆'(岩草叶叶橡子叶))
'(岩草橡子叶叶)
答案 1 :(得分:0)
这样做非常简单:
(define (leaf? v)
(eq? v 'leaf))
(define (leafpile lst)
(append (filter (compose not leaf?) lst)
(filter leaf? lst)))
除非您遇到性能问题,否则我不需要做更多事情,而且我通常不喜欢小型列表。我倾向于认为少于一百万个元素的列表很小。显而易见的递归可能不会更快:
(define (leafpile lst)
(local [(define (leafpile lst n) ; screaming for a named let here!
(cond
((null? lst) (make-list n 'leaf))
((leaf? (car lst)) (leafpile (cdr lst) (add1 n)))
(else (cons (car lst) (leafpile (cdr lst) n)))))]
(leafpile lst 0)))
尾递归,累加非叶值,计算叶值并使用srfi / 1 append-reverse!
产生最终结果:
(require srfi/1)
(define (leafpile lst)
(local [(define (leafpile lst acc n) ; I'm still screaming
(cond
((null? lst) (append-reverse! acc (make-list n 'leaf)))
((leaf? (car lst)) (leafpile (cdr lst) acc (add1 n)))
(else (leafpile (cdr lst) (cons (car lst) acc) n))))]
(leafpile lst '() 0)))