我正忙着阅读lua第4版中的程序设计,并且正为第二章苦苦挣扎。该程序实质上是打印一个棋盘,棋盘上有8个皇后,每个皇后都不能互相攻击。我要弄清楚的是为什么它要多次印刷电路板。
我已经逐步检查了代码,一旦打印解决方案完成了对第一块板的打印,我以为它将结束功能,然后跳回主菜单,但由于某种原因,它会不断循环播放。我对lua还是很陌生,刚从C来,所以仍然习惯了这一切。
其输出的一块板的图像。 X是皇后-https://ibb.co/KsT3R8X
N = 8 -- board size
-- check whether position (n,c) is free from attacks
function isplaceok (a, n, c)
for i = 1, n - 1 do -- for each queen already placed
if (a[i] == c) or -- same column?
(a[i] - i == c - n) or -- same diagonal?
(a[i] + i == c + n) then -- same diagonal?
return false -- place can be attacked
end
end
return true -- no attacks; place is OK
end
-- print a board
function printsolution (a)
for i = 1, N do -- for each row
for j = 1, N do -- and for each column
-- write "X" or "-" plus a space
io.write(a[i] == j and "X" or "-", " ")
end
io.write("\n")
end
io.write("\n")
end
-- add to board 'a' all queens from 'n' to 'N'
function addqueen (a, n)
if n > N then -- all queens have been placed?
printsolution(a)
else -- try to place n-th queen
for c = 1, N do
if isplaceok(a, n, c) then
a[n] = c -- place n-th queen at column 'c'
addqueen(a, n + 1)
end
end
end
end
-- run the program
addqueen({}, 1)
答案 0 :(得分:1)
程序正在为8x8棋盘打印所有92种可能的解决方案。 可能是出于此目的,因此它似乎可以正常工作。
要在找到1个解决方案后停止,我们可以向程序添加变量found
:
local found = false
-- print a board
function printsolution (a)
for i = 1, N do -- for each row
for j = 1, N do -- and for each column
-- write "X" or "-" plus a space
io.write(a[i] == j and "X" or "-", " ")
end
io.write("\n")
end
io.write("\n")
found = true
end
-- add to board 'a' all queens from 'n' to 'N'
function addqueen (a, n)
if n > N then -- all queens have been placed?
printsolution(a)
else -- try to place n-th queen
for c = 1, N do
if isplaceok(a, n, c) and found == false then
a[n] = c -- place n-th queen at column 'c'
addqueen(a, n + 1)
end
end
end
end
此found
变量在我们返回堆栈时停止了现有循环的继续递归。
现在为什么这段代码如此工作,所有解决方案都从哪里来?
这与for
中的addqueen
循环有关:</ p>
for c = 1, N do
if isplaceok(a, n, c) then
a[n] = c
addqueen(a, n + 1)
end
end
for循环的每个循环通过递归调用addqueen
来发送更深的代码。堆栈永远不会比9更深,因为这是N
设置的限制
114个调用addqueen
之后的第一个解决方案是:
X - - - - - - -
- - - - X - - -
- - - - - - - X
- - - - - X - -
- - X - - - - -
- - - - - - X -
- X - - - - - -
- - - X - - - -
第5个解决方案是我们第一次回到最初的调用addqueen
,您可以看到第一个X从1x1移到了1x2(n = 1 c = 2,这是我们第二步原始的for循环):
- X - - - - - -
- - - X - - - -
- - - - - X - -
- - - - - - - X
- - X - - - - -
X - - - - - - -
- - - - - - X -
- - - - X - - -
最后,我们调用addqueen
1952次,以便程序检查所有可能的解决方案。
您可以调整代码以打印深度值,以更好地了解程序运行时堆栈的外观:
-- add to board 'a' all queens from 'n' to 'N'
function addqueen (a, n)
print(n .. "↓")
if n > N then -- all queens have been placed?
printsolution(a)
else -- try to place n-th queen
for c = 1, N do
if isplaceok(a, n, c) then
a[n] = c -- place n-th queen at column 'c'
addqueen(a, n + 1)
end
end
end
print(n - 1 .. "↑")
end