【问题标题】:Why Is This Tail-Recursive Function So Much More Complicated?为什么这个尾递归函数要复杂得多?
【发布时间】:2015-01-29 02:27:37
【问题描述】:

所以,我在摆弄一些基本的数学,我想要一个在基数之间转换的函数。

我写了这个函数:

(define (convert-base from to n)
  (let f ([n n])
    (if (zero? n)
        n
        (+ (modulo n to) (* from (f (quotient n to)))))))

这适用于我所有的个人测试 以 10 为基数的功能非常好。

让我感到困惑的是,当我尝试使函数尾递归时,我最终陷入了混乱(我添加了一些间距以利于 SO,因为我的代码通常不清晰或不漂亮):

;e.g. 10 2 10 should output 1010, 10 8 64 should output 100 etc.

(define (convert-base-tail from to n)
  (let f ([n n]
          [acc 0]
          [zeros 0])

    (begin (printf "n is ~a. acc is ~a. zeros are ~a.\n" n acc zeros)

    (cond [(zero? n) (let exp 
                       ([x acc]
                        [shft zeros])
                       (if (zero? shft)
                           x
                           (exp (* x 10) (- shft 1))))]
          [(zero? (modulo n to))
            (if (zero? acc)
                (f (quotient n to) (* acc from) (add1 zeros))
                (f (quotient n to) (* acc from) zeros))]
          [else (f (quotient n to) (+ (* acc from) (modulo n to)) zeros )]))))

我的问题是,本质上,为什么尾递归函数要复杂得多?由于问题的性质,这是不可避免的,还是由于我的疏忽?

【问题讨论】:

    标签: recursion racket tail-recursion


    【解决方案1】:

    其实不然:

    (define (convert-base from to n)
      (let f ([n n] [mul 1] [res 0])
        (if (zero? n)
            res
            (f (quotient n to) (* mul from) (+ res (* mul (modulo n to)))))))
    

    测试

    > (convert-base-y 10 2 10)
    1010
    > (convert-base-y 10 8 64)
    100
    

    【讨论】:

    • 谢谢!我以为会有更好的方法来接近它,但我只是错过了,我只是完全阻止了它。真令人沮丧。这更有意义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多