使用memoization计算组合nCk的方案

时间:2016-10-28 02:41:55

标签: scheme lisp racket

我正在尝试计算nCk在球拍/方案中使用记忆的组合方式

我不能使用单独的递归方法来计算n!。 我做到了这一点,但说这是不好的syntex 我实际上修复了不好的syntex错误! 但仍然得到一个错误(let([ans(assoc(x y)memo part!。 有谁知道我做错了什么?

 (define combm
  (letrec ([memo null]
           [f (lambda (x y)
                (let ([ans (assoc (x y) memo)])
                  (if ans
                      (cdr ans)
                      (let ([new-ans (letrec ([fac (lambda (x)
                                      (if (eq? x 0)
                                          1
                                          (* x (fac (- x 1)))))])
                        (/ (fac x) (* (fac y) (fac (- x y)))))])
                        (begin
                          (set! memo (cons (cons (x y) new-ans) memo))
                          new-ans)))))])
    f))

                                     `

2 个答案:

答案 0 :(得分:1)

这个表达式(assoc (x y) memo)是恐怖的原因。

如果您在combm中应用(combm 42 43),则会(assoc (x y) memo)成为(assoc (42 43) memo) (42 43)。并且(assoc (list x y) memo)表示“将值42应用于43”。问题是42不是一个功能。

请尝试!/bin/bash TMPDIR=/home/david/tmp ip_targets(){ while IFS= read -r file_name; do echo "This is: $file_name" grep -woE "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" $file_name done < <(find "$TMPDIR" -regex '.*.vms$') } ip_targets

答案 1 :(得分:0)

这是一个可能的解决方案,它会记住阶乘函数:

(define combm
  (let ((memo '()))
    (lambda (n r)
      (letrec ((fact (lambda (n)
                       (let ((ans (assoc n memo =)))
                         (if ans
                             (cadr ans)
                             (if (< n 2)
                                 1
                                 (let ((res (* n (fact (sub1 n)))))
                                   (set! memo (cons (list n res) memo))
                                   res)))))))
        (/ (fact n) (* (fact r) (fact (- n r))))))))

因为它在组合公式中被多次使用,因此对于因子的记忆是必要的。