Golang数独算法不起作用

Golang数独算法不起作用,go,sudoku,recursive-backtracking,Go,Sudoku,Recursive Backtracking,我对Golang很陌生,我正在尝试用回溯算法做一个数独游戏。 但是当我运行我的程序时,没有错误,但它只显示网格未完成,空的情况下,这是我的代码: package main import "fmt" var sudoku = [9][9]int{ {9, 0, 0, 1, 0, 0, 0, 0, 5}, {0, 0, 5, 0, 9, 0, 2, 0, 1}, {8, 0, 0, 0, 4, 0, 0, 0, 0}, {0, 0, 0, 0, 8, 0, 0,

我对Golang很陌生,我正在尝试用回溯算法做一个数独游戏。 但是当我运行我的程序时,没有错误,但它只显示网格未完成,空的情况下,这是我的代码:

package main

import "fmt"

var sudoku = [9][9]int{
    {9, 0, 0, 1, 0, 0, 0, 0, 5},
    {0, 0, 5, 0, 9, 0, 2, 0, 1},
    {8, 0, 0, 0, 4, 0, 0, 0, 0},
    {0, 0, 0, 0, 8, 0, 0, 0, 0},
    {0, 0, 0, 7, 0, 0, 0, 0, 0},
    {0, 0, 0, 0, 2, 6, 0, 0, 9},
    {2, 0, 0, 3, 0, 0, 0, 0, 6},
    {0, 0, 0, 2, 0, 0, 9, 0, 0},
    {0, 0, 1, 9, 0, 4, 5, 7, 0},
  }

func main(){
  IsValid(sudoku, 0)
  Display(sudoku)
}

func Display(sudoku[9][9] int){
  var x, y int

  for x = 0; x < 9; x++ {
        fmt.Println("")
        if(x == 3 || x == 6){
          fmt.Println(" ")
        }
      for y = 0; y < 9; y++ {
        if(y == 3 || y == 6){
          fmt.Print("|")
        }
         fmt.Print(sudoku[x][y])
      }

   }

}

func AbsentOnLine(k int, sudoku [9][9]int, x int) bool {
  var y int
    for y=0; y < 9; y++ {
        if (sudoku[x][y] == k){
            return false
          }
        }
    return true
}

func AbsentOnRow(k int, sudoku [9][9]int, y int) bool {
  var x int
  for x=0; x < 9; x++{
       if (sudoku[x][y] == k){
           return false;
         }
       }
   return true;
}

func AbsentOnBloc(k int, sudoku [9][9]int, x int, y int) bool {
  var firstX, firstY int;
  firstX =  x-(x%3)
  firstY =  y-(y%3)
  for x = firstX; x < firstX+3; x++ {
        for y = firstY; y < firstY+3; y++ {
            if (sudoku[x][y] == k){
                return false;
              }
        }
      }
    return true;

}

func IsValid(sudoku [9][9]int, position int) bool {

  if (position == 9*9){
        return true;
      }

      var x, y, k int

    x = position/9
    y = position%9

    if (sudoku[x][y] != 0){
        return IsValid(sudoku, position+1);
      }

    for k=1; k <= 9; k++ {
        if (AbsentOnLine(k,sudoku,x) && AbsentOnRow(k,sudoku,y) && AbsentOnBloc(k,sudoku,x,y)){
            sudoku[x][y] = k;

            if (IsValid(sudoku, position+1)){
                return true;
              }
        }
    }
    sudoku[x][y] = 0;
    return false;

}

我不明白为什么它没有完成网格,有人有什么想法吗?

我不知道Golang,但我已经编写了一个使用回溯的数独求解算法

你的代码只在电路板上迭代一次。你从
position=0开始,你的代码在电路板上迭代,如果某个位置的值为零,你尝试值1-9,如果不起作用,你就转到下一个位置。当
position=81
时,代码停止

您使用
Isvalid
函数向电路板添加了新值,但您没有再次迭代新电路板,以查看这些新值是否有助于
AbsentOn…
函数返回与上一次迭代不同的新值。你必须一次又一次地迭代你的电路板,直到你确定没有
0
值的单元

这就是为什么在课程结束时,你必须在黑板上添加许多
0
。你的程序只迭代了一次,在它是无法解决你的例子数独上它的第一次尝试。它必须为数独板添加新的值,并在每次迭代中使数独板变得更容易


另一个问题是您的代码没有提供反馈。例如,它为空单元格提供
1
。一开始这似乎没有问题,但这并不意味着该单元格的最终值必须是
1
。它可能会更改,因为在下一次迭代中,您意识到另一个单元格只能接受值
1
,因此现在您必须更改回初始单元格,并找到除
1
之外的新值。您的代码也无法做到这一点。这就是为什么人类在不确定的情况下在细胞附近放置一些可能的值



看起来你的问题出在算法上。你必须了解回溯算法。您可以先用您熟悉的另一种语言进行尝试,然后将其迁移到golang(我用C++编写了我的)。除此之外,你的golang代码很容易阅读,我没有看到任何与golang相关的问题

您的
IsValid
函数更改数独的内容。问题是,实际上,在你的代码中,它只改变了数独的一个副本。如果它应该更改实际变量,则需要将其作为指针传递

以下是您需要在代码中进行的更改,只需五个字符:

func main() {
    IsValid(&sudoku, 0)
    Display(sudoku)
}

// ...

func IsValid(sudoku *[9][9]int, position int) bool {

// ...

if AbsentOnLine(k, *sudoku, x) && AbsentOnRow(k, *sudoku, y) && AbsentOnBloc(k, *sudoku, x, y) {

很抱歉你的评论看起来很轻快,但是你试过调试吗?你不希望我们代表你做这件事,对吗?:)从不期望任何人代表我做事,只是一些想法,没有代码是很好的:DThx为你回答实际上它工作我只是没有调用isValid函数中的显示函数在网格完成后显示,但现在它工作了请注意,发布的程序在算法上工作,这只是一个编程错误,因为不知道数组和指针在Go中是如何工作的,请参阅我的答案。
func main() {
    IsValid(&sudoku, 0)
    Display(sudoku)
}

// ...

func IsValid(sudoku *[9][9]int, position int) bool {

// ...

if AbsentOnLine(k, *sudoku, x) && AbsentOnRow(k, *sudoku, y) && AbsentOnBloc(k, *sudoku, x, y) {