Common-LISP 调试(包含代码)
Common-LISP debugging (code included)
我希望快速修复我的代码,该代码包含数字列表、数字列表和阈值以及 return 数字列表中大于阈值的项目数。我就是想不通哪里出了问题,也不熟悉调试。我对 Whosebug 和 LISP 还很陌生……欢迎任何 comments/criticism/advice。谢谢!
ex) (count-greater-than (list 1 2 3 4 5 6 6 7) 5) => 3
(defun count-greater-than (numberlist threshold)
(if (null numberlist) 0
(counter (numberlist threshold 0)))
(defun counter (numberlist threshold count)
(cond ((null numberlist) count)
((> (first numberlist) threshold) (counter (rest numberlist) threshold (+ 1 count)))
(t (counter (rest numberlist) threshold count)))))
首先,请注意该标准实际上包含有助于解决此类问题的功能。有一个有用的 count-if 函数可以接受一个谓词并计算列表中有多少元素满足它。对于你的情况,你可以这样做:
CL-USER> (count-if #'(lambda (x)
(> x 5))
(list 1 2 3 4 5 6 6 7))
;=> 3
CL-USER> (defun count-greater-than (numbers threshold)
(count-if (lambda (n) (> n threshold)) numbers))
COUNT-GREATER-THAN
CL-USER> (count-greater-than (list 1 2 3 4 5 6 6 7) 5)
3
CL-USER> (count-greater-than (list 1 2 3 4 5 6 6 7) 6)
1
在您的特定情况下,您似乎是手动执行此操作,但括号错误。看起来您正在尝试创建一个名为 counter 的本地辅助函数。您可以使用 defun 在函数外部定义它,例如:
(defun count-greater-than (numberlist threshold)
(if (null numberlist) 0
(counter (numberlist threshold 0))))
(defun counter (numberlist threshold count)
(cond ((null numberlist) count)
((> (first numberlist) threshold) (counter (rest numberlist) threshold (+ 1 count)))
(t (counter (rest numberlist) threshold count))))
或者您可以使用 labels:
使用本地定义来完成
(defun count-greater-than (numberlist threshold)
(labels ((counter (numberlist threshold count)
(cond ((null numberlist) count)
((> (first numberlist) threshold) (counter (rest numberlist) threshold (+ 1 count)))
(t (counter (rest numberlist) threshold count)))))
(if (null numberlist) 0
(counter numberlist threshold 0))))
备注
正如 Xach 在评论中指出的那样,您实际上可以使用 count 的 :test 参数更简洁地执行此操作。我不知道它是否明确地捕捉了 "count things with this property" 的概念,但它提供了一个非常简短的解决方案:
CL-USER> (count 5 (list 1 2 3 4 5 6 6 7) :test #'<)
;=> 3
这会计算 5 在列表中出现的次数,但诀窍在于,而不是使用 eql 或 =[ 检查列表元素是否为 5 =46=],它使用<。也就是说,count 将最终检查 (< 5 1),然后 (< 5 2) , …, 直到 (< 5 6), (< 5 7)。它 是 指定将使用该顺序的参数调用测试。 glossary entry on satisfy the test 表示(强调):
- (for a two argument test) to be in a state such that the two-place predicate which is the sequence function's test argument returns true
when given a first argument that is the object being considered, and
when given a second argument that is the result of calling the
sequence function's key argument on an element of the sequence
function's sequence argument which is being tested for equality;
我希望快速修复我的代码,该代码包含数字列表、数字列表和阈值以及 return 数字列表中大于阈值的项目数。我就是想不通哪里出了问题,也不熟悉调试。我对 Whosebug 和 LISP 还很陌生……欢迎任何 comments/criticism/advice。谢谢!
ex) (count-greater-than (list 1 2 3 4 5 6 6 7) 5) => 3
(defun count-greater-than (numberlist threshold)
(if (null numberlist) 0
(counter (numberlist threshold 0)))
(defun counter (numberlist threshold count)
(cond ((null numberlist) count)
((> (first numberlist) threshold) (counter (rest numberlist) threshold (+ 1 count)))
(t (counter (rest numberlist) threshold count)))))
首先,请注意该标准实际上包含有助于解决此类问题的功能。有一个有用的 count-if 函数可以接受一个谓词并计算列表中有多少元素满足它。对于你的情况,你可以这样做:
CL-USER> (count-if #'(lambda (x)
(> x 5))
(list 1 2 3 4 5 6 6 7))
;=> 3
CL-USER> (defun count-greater-than (numbers threshold)
(count-if (lambda (n) (> n threshold)) numbers))
COUNT-GREATER-THAN
CL-USER> (count-greater-than (list 1 2 3 4 5 6 6 7) 5)
3
CL-USER> (count-greater-than (list 1 2 3 4 5 6 6 7) 6)
1
在您的特定情况下,您似乎是手动执行此操作,但括号错误。看起来您正在尝试创建一个名为 counter 的本地辅助函数。您可以使用 defun 在函数外部定义它,例如:
(defun count-greater-than (numberlist threshold)
(if (null numberlist) 0
(counter (numberlist threshold 0))))
(defun counter (numberlist threshold count)
(cond ((null numberlist) count)
((> (first numberlist) threshold) (counter (rest numberlist) threshold (+ 1 count)))
(t (counter (rest numberlist) threshold count))))
或者您可以使用 labels:
使用本地定义来完成(defun count-greater-than (numberlist threshold)
(labels ((counter (numberlist threshold count)
(cond ((null numberlist) count)
((> (first numberlist) threshold) (counter (rest numberlist) threshold (+ 1 count)))
(t (counter (rest numberlist) threshold count)))))
(if (null numberlist) 0
(counter numberlist threshold 0))))
备注
正如 Xach 在评论中指出的那样,您实际上可以使用 count 的 :test 参数更简洁地执行此操作。我不知道它是否明确地捕捉了 "count things with this property" 的概念,但它提供了一个非常简短的解决方案:
CL-USER> (count 5 (list 1 2 3 4 5 6 6 7) :test #'<)
;=> 3
这会计算 5 在列表中出现的次数,但诀窍在于,而不是使用 eql 或 =[ 检查列表元素是否为 5 =46=],它使用<。也就是说,count 将最终检查 (< 5 1),然后 (< 5 2) , …, 直到 (< 5 6), (< 5 7)。它 是 指定将使用该顺序的参数调用测试。 glossary entry on satisfy the test 表示(强调):
- (for a two argument test) to be in a state such that the two-place predicate which is the sequence function's test argument returns true when given a first argument that is the object being considered, and when given a second argument that is the result of calling the sequence function's key argument on an element of the sequence function's sequence argument which is being tested for equality;