提前终止程序并返回列表

时间:2017-03-12 17:40:24

标签: scheme lisp

我有一个递归代码,需要在条件满了时终止它。我能够在条件时显示列表,但是在堆栈上还有另外一个我不需要处理的调用,这些调用不允许我返回列表。

2 个答案:

答案 0 :(得分:1)

最好的方法是使用累加器。然后中止就是没有递归。

(define (copy-unless-contains-5 lst)
  (define (helper lst acc)
    (cond
      ((null? lst) (reverse acc))
      ((equal? (car lst) 5) #f) 
      (else (helper (cdr lst) (cons (car lst) acc)))))
  (helper lst '()))

如果您使用延续进行递归并且这是执行此操作的最佳方式,那么call-with-current-continuation可以为您提供一种方法来中止等待延续并选择要返回的内容。

(define (copy-unless-contains-5 lst)
  (call-with-current-continuation
   (lambda (abort)
     (define (helper lst)
       (cond
         ((null? lst) '())
         ((equal? (car lst) 5) (abort #f)) 
         (else (cons (car lst) (helper (cdr lst))))))
     (helper lst))))

毋庸置疑,最后一个版本过于复杂。两者都是一样的:

(copy-unless-contains-5 '(1 2 3 4))   ; ==> (1 2 3 4)
(copy-unless-contains-5 '(1 2 5 3 4)) ; ==> #f

答案 1 :(得分:1)

Sylwester解决方案的变体:

(define (example n)
  (call-with-current-continuation
   (lambda (return)
     (let loop ([n 0])
       (if (= n 5) ; done
           (return 'the-result)
           (loop (+ n 1)))))))

(example 10)

以这种方式使用continuation允许使用转义延续而不是call/ec的完整延续(如果你的实现具有转义延续)。