所以我写了一些东西,给出一个正整数列表返回一个最大子集和。但是,我想使用(let)以便我使代码更有效。我想知道是否或如何可能。
(defun subset-sum1 (numbers capacity)
(subset-sum numbers capacity 0))
(defun subset-sum (numbers capacity counter)
(cond ((null numbers) counter)
((= counter capacity) counter) ;; return if counter 'hits' the capacity
((< capacity (+ (car numbers) counter))
(subset-sum (cdr numbers) capacity counter)) ;; cdr if car branch exceeds capacity
((<= (subset-sum (cdr numbers) capacity counter)
(subset-sum (cdr numbers) capacity (+ (car numbers) counter)))
(subset-sum (cdr numbers) capacity (+ (car numbers) counter))) ;; choose car
(t (subset-sum (cdr numbers) capacity counter)))) ;; choose cdr
以上代码在常见的lisp中运行良好。但是,我想做类似下面的事情,因为我觉得使用let会使代码变得更好。但是我写的内容进入无限循环:( 这是一个介绍AI课程的作业......请帮助新手!
(defun subset-sum (numbers capacity counter)
(let ((exclude (subset-sum (cdr numbers) capacity counter))
(include (subset-sum (cdr numbers) capacity (+ (car numbers) counter))))
(cond ((null numbers) counter)
((= counter capacity) counter)
((< capacity (+ (car numbers) counter)) exclude)
((<= exclude include) include)
(t (exclude)))))
答案 0 :(得分:1)
由于这些行,你得到一个无限循环:
(defun subset-sum (numbers capacity counter)
(let ((exclude (subset-sum (cdr numbers) capacity counter))
你一直在递归地调用 subset-sum ,它永远不会终止。即使你到达列表的末尾,数字是(),你仍然继续,因为(cdr'(())是的'()即可。您通过检查(空号码)来处理原始内容(尽管使用(endp numbers)可能更惯用)。现在你可以做类似的事情:
(defun subset-sum (numbers capacity counter)
(if (endp numbers)
counter
(let ((exclude (subset-sum (cdr numbers) capacity counter))
;...
)
(cond ; ...
))))