在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))
代码不能处理大量的树木,任何帮助都会很棒!
答案 0 :(得分:1)
有两个问题:
在函数head-search2
中,cond
的第二个子句,对head-search2
的第一次递归调用无法传播check
。
相同的子句,第二次递归调用获取(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)))))
为动态编程进一步重写这一点留给读者练习。 ;)