Scheme中的递归方法

时间:2015-03-26 19:25:37

标签: list recursion scheme message-passing r5rs

我在Scheme中有一个(理论上)简单的方法,它必须使用递归。问题是我似乎无法弄清楚递归部分...我有一个程序需要一个'指针'和任意多个参数,我需要将参数逐个传递给另一个方法。这是我到目前为止所得到的:

(define (push-elements ptr . args)
    (define (push-all ptr list)
        (if (null? list)
            '()
            (ptr 'push-elements (car list))))
     (push-all ptr list))

我知道这里没有递归,但我无法理解放在哪里/怎么做。这个想法很清楚,里面是“全力以赴”。我需要打电话:

(push-all ptr (cdr list))

如果有人可以帮助我(我会非常感谢如何制作这种递归方法的解释),那就太棒了。

2 个答案:

答案 0 :(得分:1)

考虑基本案例和每个增量案例是有帮助的。如果您尝试全部推送到堆栈但没有项目,结果应该是什么?只是堆栈。如果你尝试全部推送到一个堆栈上并且你有多个项目,那么结果是什么?好吧,首先你要把第一个项目推到堆栈上,给你一个新的堆栈。然后,您可以全部 rest 项目放到该堆栈中:

(define (push-all stack items)
  (if (null? items)
      stack
      (let ((new-stack (cons (car items) stack))
            (remaining-items (cdr items)))
        (push-all new-stack remaining-items))))

(display (push-all '(1 2) '(a b c)))
;=> (c b a 1 2)

现在,您的原始版本是可变的。也就是说,由于虚线arglist,它接受任何数字(好,大于零)的参数。这没关系,但这确实意味着您需要在设置递归调用时使用 apply

(define (push-all stack . items)
  (if (null? items)
      stack
      (let ((new-stack (cons (car items) stack))
            (remaining-items (cdr items)))
        (apply push-all new-stack remaining-items))))

(display (push-all '(1 2) 'a 'b 'c))
;=> (c b a 1 2)

答案 1 :(得分:0)

基本上,您正在实施for-each的变体,就像副作用一样map

(define (for-each procedure lst)
  (let loop ((lst lst))
    (if (null? lst)        
        'undefined-value
        (begin
          (procedure (car lst))
          (loop (cdr lst))))))

(for-each display (list 1 2 3 4)) ; prints 1234

但是您希望能够将值指定为参数,因此您需要将lst更改为rest参数:

(define (for-each-arg procedure . lst) ; changed to dotted list / rest here
  (let loop ((lst lst))
    (if (null? lst)        
        'undefined-value
        (begin
          (procedure (car lst))
          (loop (cdr lst))))))

(for-each-arg display 1 2 3 4) ; prints 1234

如果你想要一种更实用的方法,你确实要制作地图或折叠。也许首选左侧是首选:

(define (fold-args join init . lst)
  (let loop ((acc init) (lst lst))
    (if (null? lst)
        acc
        (loop (join (car lst) acc) (cdr lst)))))

(fold-args cons '() 1 2 3 4) ; ==> (4 3 2 1)

您实际上可以使用此实现for-each-arg

(define (for-each-arg procedure . lst)
  (apply fold-args 
         (lambda (x acc) 
           (procedure x) 
           'undefined) 
         'undefined 
         lst))

(for-each-arg display 1 2 3 4) ; => undefined-value; prints 1234