在Scheme中存储返回值

时间:2018-04-06 23:10:22

标签: list recursion scheme reverse let

 (define (odds lst)
    (if (null? lst)
      lst
      (cons (car lst)
            (if (or (null? lst)
                    (not (pair? (cdr lst))))
              '()
              (odds (cddr lst)))))
      )

此函数返回奇数元素;我的问题是,我想获取它返回的列表并将其反转(使用内置的reverse函数)。我一直试图使用lambda来存储它,但结果也没有改变,也尝试使用set-cons!也无济于事。在递归函数中使用let的概念似乎让我感到震惊。如果有人能指出我正确的方向,那将非常感激!

3 个答案:

答案 0 :(得分:0)

这是一个使用let *

存储返回和结果的片段
(define (odds lst)    
  (if(null? lst)
    lst
    (cons (car lst)
       (if (or (null? lst)
               (not(pair? (cdr lst))))
       '()
        (odds (cddr lst))))))

(define data (odds `(1 2 3 4 5 6 7 8 9) ) )

(let ((rev_odds ( reverse data  )))
   ;do stuff with results
   (display rev_odds)
     )

答案 1 :(得分:0)

将函数的结果传递给您想要反转列表的地方的reverse

> (odds '(a b c d e))
'(a c e)
> (reverse (odds '(a b c d e)))
'(e c a)
> (let ((o (reverse (odds '(a b c d e))))) (append o o))
'(e c a e c a)
> (define (reverse-odds ls) (reverse (odds ls)))
> (reverse-odds '(5 6 a 9 "hi"))
'("hi" a 5)

答案 2 :(得分:0)

如果只是cons直接递归递归结果,您可以不必担心返回值

(define (odds lst)
  (if (null? lst)
    null
    (if (odd? (car lst))
        (cons (car lst)
              (odds (cdr lst)))
        (odds (cdr lst)))))

(odds '(0 1 2 3 4 5 6 7))
;; => '(1 3 5 7)

表示“返回”值的一种方法是向我们的递归函数添加一个参数。下面我们在辅助帮助函数acc中使用loop。使用这样的参数是将递归调用移动到tail position

的一种常用方法
(define (odds lst)
  (define (loop acc lst)
    (if (null? lst)
        (reverse acc)
        (if (odd? (car lst))
            (loop (cons (car lst) acc)
                  (cdr lst))
            (loop acc
                  (cdr lst)))))
  (loop null lst))

(odds '(0 1 2 3 4 5 6 7))
;; => '(1 3 5 7)

另一种方法是通过下面的cont来表示我们的返回值。我们只需使用我们希望返回的值调用cont。在这种情况下,递归调用看起来有点复杂,因为我们必须构造一个代表 new 返回值的lambda。这里的额外好处是odds按顺序构造结果;不再需要reverse

(define (odds lst (cont identity))
  (if (null? lst)
      (cont null)
      (if (odd? (car lst))
          (odds (cdr lst) (lambda (acc)
                            (cont (cons (car lst) acc))))
          (odds (cdr lst) cont))))

(odds '(0 1 2 3 4 5 6 7))
;; => '(1 3 5 7)