Lisp Coin Toss Heads序列

时间:2012-03-08 13:47:12

标签: tree count lisp

在Lisp中,我必须创建一个执行以下操作的程序(请访问链接):

http://uva.onlinejudge.org/external/103/10328.html

我有创建树的代码

(defun head-tail (n  &optional (total 0))
  (if (< total n)
      (list(cons 'H (head-tail n (1+ total)))
             (cons 'T (head-tail n (1+ total))))
    nil))

然后编码以检查H = head

的序列
(defun head-search2 (tree n &optional (total 0) (check 0))
  (cond ((null tree)
         check)
        ((listp (first tree))
         (+ (head-search2 (first tree) n total)
            (head-search2 (rest tree) n total check)))
        ((and (eq (first tree) 'H)
              (>= (1+ total) n))
         (head-search2 (rest tree) n (1+ total) 1))
        ((and (eq (first tree) 'H)
              (< (1+ total) n))
         (head-search2 (rest tree) n (1+ total) check))
        ((eq (first tree) 'T)
         (head-search2 (rest tree) n 0 check ))))

和最后一个组合这两个

的功能
(defun head-check (m n)
  (head-search2(head-tail m) n))

代码不能处理大量的树木,任何帮助都会很棒!

1 个答案:

答案 0 :(得分:1)

有两个问题:

  1. 在函数head-search2中,cond的第二个子句,对head-search2的第一次递归调用无法传播check

  2. 相同的子句,第二次递归调用获取(rest tree)作为第一个参数,这会产生一个额外的列表层;它应该是(second tree)而已。

  3. 那就是说,你遍历树两次:首先是构建,然后计算它。通过一点点仔细思考,您可以节省大量的工作,只需一次遍历它,而无需明确构建它:

    (defun count-n-runs (m n &optional (k n))
      "Count all possible binary sequences with n consecutive 1s."
      (cond ((= 0 n) (expt 2 m))
            ((= 0 m) 0)
            ((+ (count-n-runs (1- m) k k)
                (count-n-runs (1- m) (1- n) k)))))
    

    为动态编程进一步重写这一点留给读者练习。 ;)