0

我在 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))

如果有人可以帮助我(我将非常感谢有关如何进行这种递归方法的解释),那就太好了。

4

2 回答 2

1

考虑基本案例和每个增量案例是有帮助的。如果您尝试将所有内容压入堆栈但没有项目,结果应该是什么?只是堆栈。如果您尝试将所有内容都压入堆栈并且您有多个项目,那么结果是什么?好吧,首先你将第一个项目推入堆栈,给你一个新的堆栈。然后您可以将所有其余项目推该堆栈:

(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)
于 2015-03-26T20:00:20.647 回答
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
于 2015-03-26T21:39:29.190 回答