如何在DrRacket ISL / Lambda中编写一个函数,将某些项的出现移动到列表的末尾?

时间:2016-04-02 23:58:17

标签: scheme racket

我正在努力学习如何做到这一点,我知道它涉及到堆栈,但除非我看到一个功能在运行,否则我无法绕过它。我们已经给出了这个创建函数的例子,我需要一些帮助。这是:

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

但我需要在一个简单的函数中使用最少的递归传递。

2 个答案:

答案 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)))