C ++ - 解决数独游戏

时间:2011-12-06 14:39:59

标签: c++ recursion sudoku

我是C ++的新手,必须做家庭作业(数独)。我遇到了问题。

问题是要实现一个解决数独的搜索功能。

指令: 为了找到解决方案,使用递归搜索如下。假设有一个 尚未分配具有数字的字段(d1 ...... dn)(n> 1)。然后我们首先尝试 将字段分配给d1,执行传播,然后继续搜索 递归。 可能发生的是传播导致失败(场变为 空)。在这种情况下,搜索失败,需要为其中一个尝试不同的数字 田野。由于搜索是递归的,因此最后考虑的字段的下一个数字 试过了。如果没有任何数字导致解决方案,则搜索再次失败。这个 转向将导致尝试与前一个字段不同的数字,依此类推。

在通过分配字段来尝试数字d之前 它,你必须创建一个新的板作为当前板的副本(使用 复制构造函数并使用new分配堆中的板。只要 然后在副本上执行赋值。如果递归调用搜索 如果返回失败,则可以为下一个数字创建新的电路板 试过。

我试过了:

// Search for a solution, returns NULL if no solution found
Board* Board::search(void) {
    // create a copy of the cur. board
    Board *copyBoard = new Board(*this);
    Board b = *copyBoard;

    for(int i = 0; i < 9; i++){
        for(int j = 0; j < 9; j++){

              //  if the field has not been assigned, assign it with a digit 
            if(!b.fs[i][j].assigned()){
                digit d = 1;

                     // try another digit if failed to assign (1 to 9)
                while (d <=9 && b.assign(i, j, d) == false){
                        d++;


                      // if no digit matches, here is the problem, how to 
                      // get back to the previous field and try another digit?
                      // and return null if there's no pervious field 
                if(d == 10){
                      ...
                    return NULL;
                }
            }
        }
    }
    return copyBoard;
 }

另一个问题是在哪里使用递归调用?有小费吗? THX!

可在此处找到完整说明:http://www.kth.se/polopoly_fs/1.136980!/Menu/general/column-content/attachment/2-2.pdf

代码:http://www.kth.se/polopoly_fs/1.136981!/Menu/general/column-content/attachment/2-2.zip

2 个答案:

答案 0 :(得分:2)

您的代码中没有递归。您不能只访问每个字段一次并尝试为其分配值。问题是你可以将5分配给字段(3,4),它可能只是当你到达字段(6,4)时发现它不能有5(3) ,4)。最终你需要退出递归,直到你回到(3,4)并在那里尝试另一个值。

使用递归,您可能不会使用嵌套for循环访问字段,而是使用递归调用访问下一个字段。要么设法到达最后一个字段,要么尝试所有可能性,然后让函数返回到您访问过的上一个字段。


旁注:绝对不为此任务分配动态内存:

//Board *copyBoard = new Board(*this);
Board copyBoard(*this); //if you need a copy in the first place

答案 1 :(得分:1)

基本上你可以尝试的是这样的(伪代码)

bool searchSolution(Board board)
{
 Square sq = getEmptySquare(board)
 if(sq == null)
    return true; // no more empty squares means we solved the puzzle

 // otherwise brute force by trying all valid numbers
 foreach (valid nr for sq)
 {
    board.doMove(nr)

    // recurse
    if(searchSolution(board))
        return true

    board.undoMove(nr) // backtrack if no solution found
 }

 // if we reach this point, no valid solution was found and the puzzle is unsolvable
 return false;

}

getEmptySquare(...)函数可以返回一个随机空方块或剩下最少数量选项的方块。 使用后者将使算法收敛得更快。

相关问题