我对 lisp 中的多个 if 语句有疑问。如果count
不等于n
我想继续使用let
andif
语句,否则我想做(= (abs (- row i))
,如果那是t
返回 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))))
更新:
谢谢你的好回应。是的,确实我正在尝试解决 N 皇后难题 :P 我现在遇到的问题是,当行为空时,我的控制来确定是否将皇后放置在某个行和列上不起作用。那是因为getqueencol
将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))