首页 > 解决方案 > 如何不在 min-30-percent 函数中递归调用辅助函数?

问题描述

(define (sum lst finalans)
  (cond
    [(empty? lst) finalans]
    [else (+ finalans (first lst) (sum (rest lst) finalans))]))


(define (min-thirty-percent lst)
  (cond
    [(empty? lst) empty]
    [(> (first lst) (* 0.3 (sum lst 0))) (cons (first lst) (min-thirty-percent (rest lst)))]
    [else (min-thirty-percent (rest lst))]))

我已经编写了这个程序,我不想递归地计算总和。总和值随着列表的变化而变化,但我不希望这样。我希望计算一次列表的总和,然后进行比较。我怎样才能做到这一点?

标签: racket

解决方案


首先,我想指出,在您的示例中,finalans始终为 0。看起来您正在尝试在那里使用累加器,但您只是直接调用它我建议你完全删除它给你:

(define (sum lst)
  (cond
    [(empty? lst) 0]
    [else (+ (first lst) (sum (rest lst)))]))

或者,您可以通过使用sum提供的来简化它math/base

现在,您可能想要的是一个额外的伪辅助函数min-thirty-percent,它允许您计算总和一次,然后从那里进行递归调用。事实证明,Racket 的命名let语法对此非常方便:

(define (min-thirty-percent lst)
  (let loop ([lst lst]
             [min30 (* 0.3 (sum lst))])
    (cond
      [(empty? lst) empty]
      [(> (first lst) min30) (cons (first lst) (loop (rest lst) min30))]
      [else (loop (rest lst) min30)]))

虽然,因为这是一个如此简单的操作,你也可以直接使用球拍的for/list构造,完全跳过递归:

(define (min-thirty-percent lst)
  (define min30 (sum lst)
  (for/list ([i lst]
             #:when (i . > . min30))
    i))

推荐阅读