理解这个数独解算器递归函数(python)有困难

理解这个数独解算器递归函数(python)有困难,python,recursion,Python,Recursion,因此,基本上我决定用python制作一个数独解算器,递归函数是最有效的,但我一直试图从youtuber中理解这段代码,不明白为什么每个空格(bo[row][col])不会立即重置为0。只有当solve(bo)为True时,才会将一个空格重置为0,但是如果我仔细查看代码,只有当电路板完全解算时,电路板才会返回True,那么为什么这个函数不起作用,因为solve(bo)永远不会为True def solve(bo): 查找=查找为空(bo) 如果找不到: 返回True#这是唯一一次解算(bo)=Tr

因此,基本上我决定用python制作一个数独解算器,递归函数是最有效的,但我一直试图从youtuber中理解这段代码,不明白为什么每个空格(bo[row][col])不会立即重置为0。只有当solve(bo)为True时,才会将一个空格重置为0,但是如果我仔细查看代码,只有当电路板完全解算时,电路板才会返回True,那么为什么这个函数不起作用,因为solve(bo)永远不会为True

def solve(bo):
查找=查找为空(bo)
如果找不到:
返回True#这是唯一一次解算(bo)=True
其他:
行,列=查找
对于范围(1,10)内的i:
如果有效(bo,i,(row,col)):
bo[行][col]=i
如果解决(bo):
返回真值
bo[row][col]=0#但在这里,如果solve(bo)为False,它会将空间重置为0
返回错误
def有效(bo、num、pos):
对于范围(9)内的i:
如果bo[pos[0]][i]==num和pos[1]!=一:
返回错误
对于范围(9)内的i:
如果bo[i][pos[1]==num和pos[0]!=一:
返回错误
方框x=(位置[1]//3)*3
方框y=(位置[0]//3)*3
对于范围内的i(方框y,方框y+3):
对于范围内的j(框x,框x+3):
如果bo[i][j]==num和(i,j)!=销售时点情报系统:
返回错误
返回真值
def查找_为空(bo):
对于范围(9)内的y:
对于范围(9)内的x:
如果bo[y][x]==0:
返回(y,x)
返回错误

您的解释与代码中的注释之间存在一些差异,但无论如何,我会尽力解释代码

First solve()将尝试查找第一个空白点(即0)。如果找不到,那么电路板将被解算,从而返回true

如果它确实找到了一个点,那么它将尝试在那里放置数字1-9,并检查它是否与以前输入的数字一起工作。假设7起作用(我们不知道8或9是否也起作用,因为我们还没有检查)。因此,我们将空空间设置为7,然后在递归调用中传递更新后的电路板。从本质上讲,这就像是在说“如果我强迫这个点有数字7,你能找到一个解决方案吗?”

如果递归调用返回true,这意味着该点有一个7的解决方案,因此电路板有一个解决方案,因此我们返回true。如果对solve()的递归调用返回false,那么我们知道这个点中有7的电路板没有解决方案,所以我们将这个点重置为0,然后尝试8(如果需要,再尝试9)

需要记住的是,在所有递归调用中只有一块板(
bo
),换句话说,所有函数调用都在同一个变量
bo
上运行。它不会在每次进行递归调用时创建电路板的副本。如果您想了解更多原因,请查找“按引用传递”和浅拷贝与深拷贝

“每次重置”是什么意思?每个函数调用帧?如果是这样,那是因为参数只是对内存中对象的引用。一直只有一块木板。