0

我正在为数独难题编写递归求解器。我用 0 存储空白位置,以便我的程序可以更轻松地读取它们。为了更好地可视化网格,我从下标一开始存储了原始拼图。我不确定我是否完全掌握了递归,这就是问题所在。我得到的输出似乎正在解决这个难题,但它在那里留下了不应该存在的零。我认为这与我的 unsetSquare 的放置或返回语句有关。

这是输出的示例...

**************************************************
 7  4  3 | 8  2  1 | 5  6  8 
 2  6  8 | 0  9  0 | 0  1  0 
 0  0  0 | 0  0  6 | 0  0  4 
---------|---------|---------
 0  0  0 | 0  0  0 | 2  3  9 
 0  0  0 | 0  0  0 | 0  0  0 
 4  1  5 | 0  0  0 | 0  0  0 
---------|---------|---------
 9  0  0 | 5  0  0 | 0  0  0 
 0  2  0 | 0  1  0 | 7  4  0 
 0  0  0 | 2  0  0 | 9  0  5 
**************************************************
**************************************************
 7  4  3 | 8  2  1 | 5  6  9 
 2  6  8 | 0  9  0 | 0  1  0 
 0  0  0 | 0  0  6 | 0  0  4 
---------|---------|---------
 0  0  0 | 0  0  0 | 2  3  9 
 0  0  0 | 0  0  0 | 0  0  0 
 4  1  5 | 0  0  0 | 0  0  0 
---------|---------|---------
 9  0  0 | 5  0  0 | 0  0  0 
 0  2  0 | 0  1  0 | 7  4  0 
 0  0  0 | 2  0  0 | 9  0  5 
**************************************************
**************************************************
 7  4  3 | 8  2  1 | 5  6  0 
 2  6  8 | 1  9  0 | 0  1  0 
 0  0  0 | 0  0  6 | 0  0  4 
---------|---------|---------
 0  0  0 | 0  0  0 | 2  3  9 
 0  0  0 | 0  0  0 | 0  0  0 
 4  1  5 | 0  0  0 | 0  0  0 
---------|---------|---------
 9  0  0 | 5  0  0 | 0  0  0 
 0  2  0 | 0  1  0 | 7  4  0 
 0  0  0 | 2  0  0 | 9  0  5 
**************************************************
**************************************************
 7  4  3 | 8  2  1 | 5  6  0 
 2  6  8 | 2  9  0 | 0  1  0 
 0  0  0 | 0  0  6 | 0  0  4 
---------|---------|---------
 0  0  0 | 0  0  0 | 2  3  9 
 0  0  0 | 0  0  0 | 0  0  0 
 4  1  5 | 0  0  0 | 0  0  0 
---------|---------|---------
 9  0  0 | 5  0  0 | 0  0  0 
 0  2  0 | 0  1  0 | 7  4  0 
 0  0  0 | 2  0  0 | 9  0  5 
**************************************************
**************************************************
 7  4  3 | 8  2  1 | 5  6  0 
 2  6  8 | 3  9  0 | 0  1  0 
 0  0  0 | 0  0  6 | 0  0  4 
---------|---------|---------
 0  0  0 | 0  0  0 | 2  3  9 
 0  0  0 | 0  0  0 | 0  0  0 
 4  1  5 | 0  0  0 | 0  0  0 
---------|---------|---------
 9  0  0 | 5  0  0 | 0  0  0 
 0  2  0 | 0  1  0 | 7  4  0 
 0  0  0 | 2  0  0 | 9  0  5 
**************************************************

注意在第一行的末尾,它去 8 寻找解决方案,然后到 9,9 是不合法的,它已经到达 for 循环的末尾,所以它用零替换它并继续。我怎样才能让它回去在第一行尝试不同的数字以获得更完整的解决方案?

这是我的递归函数...

bool DoTheWork::addSquare(int& depth, ostream& outStream){
    for(int i = ONE; i <= NINE; ++i){
        for(int j = ONE; j <= NINE; ++j){
            if(i == NINE && j == NINE && board.getSquare(NINE, NINE) != ZERO){
                cout << i << "     " << j << endl;
                return true;
            }
            //cout << "original" << board.getSquare(i, j) << "coord: " << i << ", " << j << endl;
            if(board.getSquare(i, j) == ZERO){
                //cout << "original: " << board.getSquare(i, j) << "coord: " << i << ", " << j << endl;
                for(int k = ONE; k <= NINE; ++k){
                    board.setSquare(i, j, k);
                    board.display(outStream);
                    if(board.isLegal()){
                         return addSquare(depth, outStream);  
                    }
                    else{
                        board.unsetSquare(i, j);

                    }
                }
            }

        }
    }
    board.display(outStream);
    return false;
}
4

2 回答 2

0

我可以看到一个问题:

它应该是:

if(board.isLegal()){
   if( addSquare(depth, outStream))
       return true;  
}

表示如果整个棋盘都已解决,则回滚。

编辑考虑一下:

您将 1 放在第一个方格中,它返回 false。你不想试试put 2吗?

EDIT2 更多问题:

if(i == NINE && j == NINE && board.getSquare(NINE, NINE) != ZERO){
          cout << i << "     " << j << endl;
          return true;
}

这应该是完成检查吗?你只检查 1 个正方形。在您的样本中,它已被填充!您需要检查是否没有 0。

编辑3:

bool DoTheWork::addSquare(int& depth, ostream& outStream){
  //use flag to let you know if all completed
  bool zeroFound = false;
  for(int i = ONE; i <= NINE; ++i){
    for(int j = ONE; j <= NINE; ++j){
      //cout << "original" << board.getSquare(i, j) << "coord: " << i << ", " << j << endl;
      if(board.getSquare(i, j) == ZERO){
        zeroFound = true;
        //cout << "original: " << board.getSquare(i, j) << "coord: " << i << ", " << j << endl;
        for(int k = ONE; k <= NINE; ++k){
          board.setSquare(i, j, k);
          board.display(outStream);
          if(board.isLegal()){
            if(addSquare(depth, outStream)){
              return true;  
            }
            else{
              board.unsetSquare(i, j);
            }
          }
        }
      }
    }
  } 
  board.display(outStream);
  return !zeroFound; //true in case it is full!
}
于 2013-10-29T22:08:58.233 回答
0

事实证明,我有一些错误的顺序,而不是在正确的范围内。在使用 while 循环成功完成后,我找到了使用 for 循环的解决方案。

bool DoTheWork::addSquare(int& depth, ostream& outStream){
    for(int i = 1; i < 10; ++i){
        for(int j = 1; j < 10; ++j){
            if(board.getSquare(i, j) == 0){
                if(i == 10){
                    return true;
                }
                for(int k = 1; k <= 9; ++k){
                    board.setSquare(i, j, k);
                    if(board.isLegal() && addSquare(depth, outStream)){
                        return true;
                    }

                }
                board.unsetSquare(i, j);
                return false;

            }
        }
    }
}
于 2013-10-30T03:41:05.343 回答