tree - Lisp 抛硬币正面序列

标签 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 = heads 的序列

(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. 在函数 head-search2 中,cond 的第二个子句,对 head-search2 的第一次递归调用未能传播检查

  2. 相同的子句,第二个递归调用获取(rest tree)作为第一个参数,这导致了额外的一层列表;它应该是(second tree)

就是说,您遍历了这棵树两次:第一次是在构建时,然后是对它进行计数。稍微仔细考虑一下,您只需遍历一次就可以节省大量工作,而无需显式构造它:

(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)))))

为动态规划进一步重写这个留给读者作为练习。 ;)

关于tree - Lisp 抛硬币正面序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9618615/

相关文章:

java - Java 中的泛型/接口(interface)和树结构

java - 预排序决策二叉树打印输出

lisp - 编写一个函数 COUNT-NUMBERS 来计算列表中数字的数量

scheme - foldl 和 foldr 如何工作,在一个例子中分解?

算法 - 查找树中具有直径距离的对数?

javascript - 删除在 DFS 算法 cytoscape JS 中发现的边缘

mysql - SQL计算多个表的行数

java - java 集合中计数出现次数的优雅方法

sql - 如何对具有 NULL 值的字段进行分组?

lisp - 符号和名称不同吗?