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

基于Backtracking method的Python数独生成器代码报错:填充至(0,7)后终止

数独生成器回溯逻辑错误排查

问题描述

  • 基于回溯法编写Python数独生成器,行、列、3×3网格检查函数已单独验证正常
  • 代码从起始位置随机填充数字,不满足检查条件时循环尝试,直到符合要求
  • 运行后仅填充至(row,col)=(0,7)位置就终止,确定错误出在第73-77行

原代码

from random import choice

a = [['-','-','-', '-','-','-', '-','-','-'],\
     ['-','-','-', '-','-','-', '-','-','-'],\
     ['-','-','-', '-','-','-', '-','-','-'],\

     ['-','-','-', '-','-','-', '-','-','-'],\
     ['-','-','-', '-','-','-', '-','-','-'],\
     ['-','-','-', '-','-','-', '-','-','-'],\

     ['-','-','-', '-','-','-', '-','-','-'],\
     ['-','-','-', '-','-','-', '-','-','-'],\
     ['-','-','-', '-','-','-', '-','-','-']]

def sudoku_board():
    # 返回格式化后的数独棋盘
    board = ''
    for i in range(9):
        if i==3 or i==6: board+='\n\n'
        else: board += '\n'
        for j in range(9):
            if j==2 or j==5: board += str(a[i][j]) + '\t'
            else: board+= str(a[i][j]) + ' '
    return board

def col_check(x,y,num):
    # 检查列中是否存在重复数字,重复返回1,否则返回0
    col = 0
    for m in range(9):
        if a[m][y] == str(num):
            col = 1
            break
    return col
    
def row_check(x,y,num):
    # 检查行中是否存在重复数字,重复返回1,否则返回0
    row = 0
    for m in range(9):
        if m!=y and a[x][m] == str(num):
            row = 1
            break
    return row
    
def grid_check(x,y,num):
    # 检查3×3网格中是否存在重复数字,重复返回1,否则返回0
    grid = 0
    for m in [(x//3),(x//3)+1,(x//3)+2]:
        for n in [(y//3),(y//3)+1,(y//3)+2]:
            if a[m][n] == str(num):
                grid = 1
                break
    return grid

i,j = 0,0
while i!=8 and j!=8:
    num = [1,2,3,4,5,6,7,8,9]
    rand_num = choice(num)
    c=0
    while col_check(i,j,rand_num)==1 or row_check(i,j,rand_num)==1 or grid_check(i,j,rand_num)==1:
        if c<9:
            c+=1
            num.remove(rand_num)
            rand_num = choice(num)
        else:
            c=0
            num = [1,2,3,4,5,6,7,8,9]
            if j==True: j-=1
            else: i-=1
    a[i][j]=str(rand_num)
    if j==8:
        j=0
        if i!=8: i+=1
        else: break
    else: j+=1
    
print(sudoku_board())

错误分析与修复

核心错误点(第73-77行)

  1. 索引判断逻辑错误:j==True 是完全错误的判断——j是0-8的整数,只有j=1时会被视为True,其他非零列索引(如2-8)都会被判定为False,导致错误地回退行索引i,而非列索引j。
  2. 未清空回溯位置的数值:回溯时没有将当前位置重置为'-',之前填充的数字会留在棋盘上,干扰后续的检查逻辑。
  3. 回溯逻辑不完整:当回退到行首(j=0)时,未正确切换到上一行的最后一列(i-1,8),导致索引混乱。

修正后的回溯代码段

else:
    c=0
    num = [1,2,3,4,5,6,7,8,9]
    # 清空当前位置,避免残留数值影响后续检查
    a[i][j] = '-'
    # 正确的回溯逻辑:先回退列,列到0则回退行并将列设为8
    if j > 0:
        j -= 1
    else:
        j = 8
        i -= 1

额外修正:外层循环条件

原循环条件while i!=8 and j!=8会导致当i=8且j<8时直接终止循环,无法填充最后一行的前8个格子,应改为:

while not (i == 8 and j == 8):

修正后效果

修正后,回溯逻辑能正确回退到上一个可修改的位置并重置状态,数独棋盘可以完整填充到最后一个格子(8,8)。

内容的提问来源于stack exchange,提问作者Gayathri Sahana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 10:40:50