我对lisp中的多个if语句有疑问。如果count
不等于n
,我希望继续使用let
和if
语句,否则我想(= (abs (- row i))
,如果是t
{1}}返回nil。
但是,我发现只要count
不是n
,我就会返回nil
因为progn
总是返回块中的最后一行代码。请与我分享我如何编写程序,这样我才能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))))
}}。
getqueencol
更新:
感谢您的好评。是的,的确,我正在尝试解决N皇后拼图:P我现在遇到的问题是我的控制权确定当行为空时,是否将某女王放在某一行和列上是不行的。这是因为nil
会在行为空时返回queen-can-be-placed-here
,而(= nil NUMBER)
会有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))
。问题是,当一个女王被添加到一个空行时,我不知道检查将如何在f(%ksi) = left lbrace stack #(2 (x-a)) over ((b-a)(c-a))# #(2(b-x)) over
((b-a)(b-c)# right none
中。
以下是目前的代码:
var data=[];
data.push({'label':category,'value':newVal});
答案 0 :(得分:2)
我对lisp中的多个if语句有疑问。如果算数是 不等于n我想继续使用let和if语句, 否则我想做(=(abs( - row i)),如果是,则返回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
那就是说, 实际上 部分 。没有必要在预测中包含 let 。你可以这样做:
(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 ,这意味着您正在执行非本地退出。当测试为false时,(如果测试时)表单的值为 nil ,则'永远不会做任何有价值的事情。实际上,在没有 else 部分的情况下,在Common Lisp中使用时是一种相当普遍的风格。也就是说,(当时测试时)等同于(如果测试然后为零)和(如果测试那么)。确实,这意味着(如果......)评估为 nil ,所以 nil 是让的值>,以及预测,但你实际上并没有做任何具有预测值的东西;它只是您在循环中评估的表单。
答案 1 :(得分:0)
每次调用回溯都试图在每个可能的列上放置一个女王。这意味着当您在queen-can-be-placed-here
行调用row
时,您可以确保在 row
之后来的所有行(包括row
)都为空(你在回溯时擦掉了电路板。)
因此,您只需要通过查看具有较小行的电路板子集来检查女王是否可以正确放置在当前列col
和当前row
。
col
v
c0 v c1
r0 Q - - -
r1 - - Q -
row >> - ? - -
- - - -
只有当 以上的行<{1}}返回与guetqueencol
不同的列或处于直接对角线位置时,才会有王后(计算与col
)。所以你真的不需要计算任何东西,只要确保永远不会满足测试。
代码中存在次要问题,如变量名称,因此一旦您确定一切按预期工作,您可以在CodeReview上询问更多反馈,如果您愿意的话。
我认为适当的答案在以下扰流板部分内。
(defun queen-can-be-placed-here (row col n) "Returns t if (row,col) is a possible place to put queen, otherwise nil." (loop for r below row for c = (getqueencol r n) never (or (= col c) (= (abs (- row r)) (abs (- col c))))))