gpt4 book ai didi

lisp - 带有 progn 的 Lisp 中的嵌套 IF 语句

转载 作者:太空宇宙 更新时间:2023-11-03 18:53:40 25 4
gpt4 key购买 nike

我对 lisp 中的多个 if 语句有疑问。如果 count 不等于 n 我想继续 letif 语句,否则我想做 (= (abs (- row i)) 如果是 t 返回 nil。

但是,我发现只要 count 不是 n,我就会返回 nil,因为 progn 总是返回 block 中的最后一行代码。请与我分享我如何编写程序,以便只有当 count 不是 n 时,我才会返回 nil 当任何 or 子句是t

(loop for i below n
do (if (/= count n)
(progn
(let ((tcol (getqueencol i n)))
(if (or (= col tcol) (= (abs (- row i)) (abs (- col tcol))))
(return-from queen-can-be-placed-here nil))))
(if (= (abs (- row i)))
(return-from queen-can-be-placed-here nil))))

更新:

感谢您的好评。是的,确实我正在尝试解决 N 皇后难题 :P 我现在遇到的问题是,当该行为空时,我确定是否将皇后放置在特定行和列的控件不起作用。这是因为当行为空时 getqueencol 将返回 nil 并且在 queen-can-be-placed-here 中会有一个 (= 无数字)

为了解决这个问题,我尝试在 queen-can-be-placed-here 中创建一个计数变量,它知道一行是否为空,这样我就不会调用 getqueencol 在空行上。问题是,我不知道如何在 queen-can-be-placed-here 中检查如何将皇后添加到空行。

目前的代码如下:

(defvar *board* (make-array '(5 5) :initial-element nil)) 

(defun getqueencol (row n)
"Traverses through the columns of a certain row
and returns the column index of the queen."
(loop for i below n
do (if (aref *board* row i)
(return-from getqueencol i))))

(defun print-board (n)
"Prints out the solution, e.g. (1 4 2 5 3),
where 1 denotes that there is a queen at the first
column of the first row, and so on."
(let ((solutionlist (make-list n)))
(loop for row below n
do (loop for col below n
do (when (aref *board* row col)
(setf (nth row solutionlist) col))))
(print solutionlist)))


(defun queen-can-be-placed-here (row col n)
"Returns t if (row,col) is a possible place to put queen, otherwise nil."
(let ((count 0))
(loop for i below n ;This is the block I added to keep track of if a row is empty (count = n)
do (if (not (aref *board* row i))
(setf count (+ 1 count))))

(loop for i below n
do (if (/= count n)
(let ((tcol (getqueencol i n)))
(if (or (= col tcol) (= (abs (- row i)) (abs (- col tcol))))
(return-from queen-can-be-placed-here nil)))
(if (= (abs (- row i))) ;Here is where I don't know what to check
(return-from queen-can-be-placed-here nil)))))

(return-from queen-can-be-placed-here t))


(defun backtracking (row n)
"Solves the NxN-queen problem with backtracking"
(if (< row n)
(loop for i below n
do (when (queen-can-be-placed-here row i n)
(setf (aref *board* row i) 't)
(backtracking (+ row 1) n)
(setf (aref *board* row i) 'nil)))
(print-board n)))

(defun NxNqueen-solver (k)
"Main program for the function call to the recursive solving of the problem"
(setf *board* (make-array (list k k) :initial-element nil))
(backtracking 0 k))

最佳答案

I have a questions about multiple if-statements in lisp. If count is not equal to n I want to continue on with the let and if statements, else I want to do (= (abs (- row i)) and if that is t return nil.

一旦您开始在 if 的任一分支上拥有多个表单,使用 cond 通常会更清楚:

(cond
((/= n count) ; if n is not count, then ...
(let ...
(return-from ...))) ; maybe return something
((= (abs (- row i)) ...) ; else if |row-i] = ...,
(return-from ...))) ; return nil

也就是说,您没有ifthen 部分实际上有多个分支。无需将 let 包装在 progn 中。你可以这样做:

(if (/= count n)
(let ((tcol (getqueencol i n)))
(if (or (= col tcol) (= (abs (- row i)) (abs (- col tcol))))
(return-from queen-can-be-placed-here nil)))
(if (= (abs (- row i)))
(return-from queen-can-be-placed-here nil)))

关于从 if 返回 nil,有两件事需要考虑。您正在使用 return-from,这意味着您正在执行非本地退出。当 test 为假时,(if test then) 形式的表达式的nil,您'从来没有用那个值(value)做任何事情。实际上,在没有 else 部分的情况下,使用 when 是 Common Lisp 中相当常见的风格。也就是说,(when test then) 等同于(if test then nil)(if test then)。这确实意味着 (if ...) 的计算结果为 nil,因此 nillet 的值>,因此 progn,但您实际上 progn 的值;它只是您在循环 中评估的一种形式。

关于lisp - 带有 progn 的 Lisp 中的嵌套 IF 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32781336/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com