更新:代码应该现在编译,没有错误或警告。对前一个抱歉。我现在遇到的问题是运行时(或任何其他整数)
(NxNqueen-solver 10)
函数 getqueencol 将返回nil,因为首先在棋盘上没有皇后,因此皇后可能会有一个(=数字为零)放在这里因为tcol是零。我认为每当没有女王作为女王可以放置在这里函数的参数传递时,就会发生这种情况。
请分享一些有关如何解决此问题的建议。提前谢谢。
这是代码
(defvar *board* (make-array '(10 10) :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."
(loop for i below n
do (let ((tcol (getqueencol i n)))
(if (or (= col tcol) (= (abs (- row i)) (abs (- col tcol))))
(return-from queen-can-be-placed-here nil)))))
(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)
(return-from backtracking (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 '(k k) :initial-element nil))
(backtracking 0 k))
答案 0 :(得分:5)
你说你编译了你的代码。情况可能不是这样,因为那时你会看到编译器抱怨错误。您希望确保真正编译代码并更正代码,以便编译时没有错误和警告。
您可能希望摆脱代码中的错误/问题(请参阅Renzo的评论),然后查看算法问题。当代码包含错误时,我很难理解算法问题。
SETQ
不会引入变量,变量必须在某处定义
DEFVAR
在函数内部没有任何意义。
像(let (x (sin a)) ...)
这样的东西肯定是错的。 LET
的语法需要在绑定列表周围添加一对括号。
RETURN-FROM
将第一个参数作为要返回的现有块的名称。可选的第二个参数是返回值。获取正确的语法并从正确的块返回。
在致电MAKE-ARRAY
时指定默认值:(make-array ... :initial-element nil)
,否则不清楚它是什么。
变量*board*
未定义
<强>风格强>
LOOP
中的:for i to (1- n)
更简单for i below n
您不需要引用NIL
和T
。
(if (eq foo t) ...)
可能更简单地写为(if foo ...)
。特别是如果foo
的值为NIL
或T
。
(if foo (progn ...))
只是(when foo ...)
我不确定您声称您的代码是在编译的。它没有编译。
每个函数都有编译器警告。您应该检查编译器警告并解决问题。
(defun getqueencol (row)
"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))))
编译器抱怨:
;;;*** Warning in GETQUEENCOL: N assumed special
;;;*** Warning in GETQUEENCOL: BOARD assumed special
n
在哪里定义? board
来自哪里?
(defun print-board (board)
"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)
(setq 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))
LET
毫无意义。 (let (foo) (setq foo bar) ...)
是(let ((foo bar)) ...)
。
为什么没有定义解决方案列表?看看LET
......这没有意义。
n
来自哪里?
(defun queen-can-be-placed-here (row col)
"Returns t if (row,col) is a possible place to put queen, otherwise nil."
(loop for i below n
do (let (tcol)
(setq tcol (getqueencol i)))
(if (or (= col tcol) (= (abs (- row i)) (abs (- col tcol))))
(return-from queen-can-be-placed-here nil))))
n
来自哪里? LET
毫无意义。
(defun backtracking (row)
"Solves the NxN-queen problem with backtracking"
(if (< row n)
(loop for i below n
do (when (queen-can-be-placed-here row i)
(setf (aref board row i) 't)
(return-from backtracking (backtracking (+ row 1)))
(setf (aref board row i) 'nil))
(print-board board))))
n
来自哪里? board
定义在哪里?
(defun NxNqueen-solver (k)
"Main program for the function call to the recursive solving of the problem"
(let (n board)
(setq n k)
(setq board (make-array '(k k) :initial-element nil)))
(backtracking 0))
为什么在setq
时使用let
?本地变量n
和board
未使用。
MAKE-ARRAY
需要一个数字列表,而不是符号列表。
我建议您使用基本的Lisp介绍(Common Lisp: A Gentle Introduction to Symbolic Computation - 免费下载)和Lisp参考(CL Hyperspec)。