C++ 无法理解此应用程序中的递归

C++ 无法理解此应用程序中的递归,c++,recursion,indexing,sudoku,backtracking,C++,Recursion,Indexing,Sudoku,Backtracking,我正在为数独游戏编写一个递归解算器。我用0存储空白位置,以便我的程序可以更轻松地读取它们。为了更好地可视化网格,我从下标1开始存储原始拼图。我不确定我是否完全掌握了递归,这就是问题所在。我得到的输出似乎是在解决这个难题的轨道上,但它在那里留下了不应该存在的零。我认为这与我的方块的位置有关,或者与返回语句有关 下面是输出的一个示例 ************************************************** 7 4 3 | 8 2 1 | 5 6 8 2

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

下面是输出的一个示例

**************************************************
 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;
}
bool DoTheWork::addSquare(int&depth,ostream&outStream){
对于(int i=1;i我可以看到一个问题:

应该是:

if(board.isLegal()){
   if( addSquare(depth, outStream))
       return true;  
}
意味着如果整个电路板已解算,则回滚

编辑想想看:

你把1放在第一个方格里,它返回false。你不想试试放2吗

EDIT2 更多问题:

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

cout结果是我有些东西的顺序不正确,并且不在正确的范围内。在成功地使用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;

            }
        }
    }
}
bool DoTheWork::addSquare(int&depth,ostream&outStream){
对于(int i=1;i<10;++i){
对于(int j=1;j<10;++j){
if(board.getSquare(i,j)==0){
如果(i==10){
返回true;
}

对于(int k=1;k)您真的认为我们可以为您调试代码吗?也许您可以创建一个较小的案例来显示相同的问题。这个案例非常小。它是一个函数…就像15行代码一样。您应该删除addSquare(depth,outStream)之后的return true;并让它返回addSquare(depth,outStream);取而代之。虽然这不会解决您的问题。您也根本没有使用深度。如果您使用深度,我希望您希望通过值而不是引用进行传递。这与我现在的情况有什么不同吗,除了语法上的不同?我更改了它,您是对的,它没有解决问题,但我想知道这两种方法是否都是equal?我试过了,但没有解决问题。我相信@drescherjm提供的答案是相同的,但语法不同。如果为false,你不想返回,你想移动到下一个值。哦,我明白了,但是它仍然没有消除输出中的残留零。刚刚看到你的编辑,我已经在用我当前的code,它累坏了从1到9的所有数字。我不确定你的建议是什么,这与我已经在做的有什么不同?请原谅,如果这是显而易见的,这是新的。最后一次编辑被困在一个无限循环中,这似乎是我提出的几乎所有解决方案都会发生的情况。
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;

            }
        }
    }
}