You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python递归局部变量vs全局变量问题:数独求解器参数化改造失败求助

解决数独求解器的回溯终止问题

我来帮你搞定这个数独求解器的问题!你遇到的核心问题是递归回溯时没有在找到解后及时终止,导致已经填好的数字被后续的回溯步骤重新置为0,最终返回了未求解的初始状态。咱们一步步修改代码来解决这个问题:

第一步:移除全局变量,让函数更纯粹

原来的form_grid依赖全局变量grid,这不仅容易引发副作用,也不符合你想要接受局部参数的需求。咱们把它改成直接返回生成的数独网格:

def form_grid(puzzle_string):
    print('The Sudoku Problem')
    grid = []
    for i in range(0, len(puzzle_string), 9):
        row = puzzle_string[i:i+9]
        temp = [int(block) for block in row]
        grid.append(temp)
    printGrid(grid)  # 同步修改printGrid,让它接受grid参数
    return grid

同时调整printGrid函数,让它依赖传入的参数而非全局变量:

def printGrid(grid):
    for row in grid:
        print(row)

第二步:修复递归终止逻辑

你的solve函数最大的问题是:不管递归调用是否找到解,都会执行grid[row][col] = 0的回溯操作。正确的逻辑应该是:

  • 如果当前空格填入某个数字后,递归调用成功找到了解,就直接返回这个解,不再回溯
  • 当遍历完所有空格(说明数独已解完),直接返回当前网格作为解

修改后的solve函数如下:

def possible(grid,row,col,digit):
    for i in range(0,9):
        if grid[row][i] == digit:
            return False
    for i in range(0,9):
        if grid[i][col] == digit:
            return False
    square_row = (row//3)*3
    square_col = (col//3)*3
    for i in range(0,3):
        for j in range(0,3):
            if grid[square_row+i][square_col+j] == digit:
                return False
    return True

def solve(grid):
    for row in range(9):
        for col in range(9):
            if grid[row][col] == 0:
                for digit in range(1, 10):
                    if possible(grid, row, col, digit):
                        grid[row][col] = digit
                        # 递归求解后检查是否得到有效解
                        result = solve(grid)
                        if result is not None:
                            return result  # 找到解直接返回,跳过回溯
                        grid[row][col] = 0  # 仅当当前路径无解时才回溯
                # 所有数字都尝试过仍无解,返回None标记当前路径失败
                return None
    # 所有空格填满,返回最终解
    return grid

第三步:调整主调用逻辑

原来的调用方式需要适配修改后的函数,我们先生成网格,再求解,最后打印结果:

puzzle_string = "004300209005009001070060043006002087190007400050083000600000105003508690042910300"
sudoku_grid = form_grid(puzzle_string)
solved_grid = solve(sudoku_grid)

print("\nThe Solved Sudoku:")
printGrid(solved_grid)

为什么这样修改有效?

  • 当递归调用返回非None值时,说明找到了可行解,我们直接向上传递这个解,避免后续回溯步骤破坏已填好的数字
  • 移除全局变量后,函数逻辑更清晰,所有操作都依赖传入的参数,消除了全局状态带来的意外修改
  • 明确的终止条件让递归在找到解后立即停止,不会继续执行无效的回溯操作

现在运行代码,就能得到正确的数独解啦!

内容的提问来源于stack exchange,提问作者gaming4 mining

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:18:13