1

再帰の使い方を学ぶために数独ソルバーを作ろうとしています。ほとんどのコードが連携してうまく動作するようになったようですが、プログラムを実行すると、プログラムが動作を停止したことを示す Windows エラーが表示されます。デバッグはセグメンテーション違反を示しており、再帰が多すぎることが原因である可能性があることを他の場所で見ました。これが強引な方法であることは承知していますが、繰り返しますが、速度よりも機能させることの方が心配です。これを作業レベルに修正するにはどうすればよいですか?

struct Playing_grid {
    //Value of cell
    int number;
    //wether the number was a clue or not
    bool fixed;
}
grid[9][9];

    void recursiveTest(int row, int column, int testing)
    {
    //first, check to make sure it's not fixed
        if(grid[row][column].fixed == false)
        {
            if((checkRow(testing, row) | checkColumn(testing, column) | checkBox(testing,boxNumber(row,column)) | (testing > 9)) == 0)
            {
                grid[row][column].number = testing;
                moveForward(row,column,testing);
                recursiveTest(row, column, testing);
            }
            else if(testing < 9)
            {
                testing ++;
                recursiveTest(row, column, testing);
            }
            else if(testing == 9)
            {
                while(testing == 9)
               {
                moveBack(row,column,testing);
                while(grid[row][column].fixed == true)
                {
                    {
                        moveBack(row,column,test);
                    }
                }
                testing = grid[row][column].number;
                recursiveTest(row,column,testing);
               }
            }
        }
        else
        {
            moveForward(row,column,testing);
            recursiveTest(row,column,testing);
        }
    }



     void moveForward(int& row, int& column, int& test)
{
    if(column < 8)
    {
        column ++;
    }
    else if((column == 8) & (row != 8))
    {
        column = 0;
        row ++;
    }
    else if((column == 8) & (row == 8))
    {
        finishProgram();
    }
    test = 1;
}

    void moveBack(int& row, int& column, int& test)
    {
        grid[row][column].number = 0;
        if(column > 0)
            {
                column --;
            }
        else if((column == 0) & (row > -1))
            {
                column = 8;
                row --;
            }
        else
        {
            cout << "This puzzle is unsolveable!" << endl;
        }
        test++;
    }

関連するすべての部分を含めようとしました。私は基本的に 9x9 マトリックスを作成します。この時点までに 81 個の値で満たされ、空のスロットは 0 として書き込まれます。テスト値が行、列、およびボックスで有効であることを確認した後、その値を入力し、次のスペース。9 まで実行され、可能な値がない場合は常に、前の値に戻り、その値を実行します。

既知の値を上書きしないように、再帰関数は grid[row][column].fixed の値が false であることを毎回チェックします。

これをクリーンアップしたり、凝縮したりするなどの洞察をいただければ幸いです。よろしくお願いします。

編集:再帰ループを終了するには、関数が呼び出されて前進するときに、最後のセルに到達した場合、ソリューションを完了(保存+出力)します。これを反映するようにコードが調整されました。

4

1 に答える 1

0

私は通常、あなたのコードを修正しようとしますが、この場合は根本的に欠陥があり、設計図に戻る必要があると思います.

原則として、このような再帰関数の擬似コードは次のようになります。

For each possible (immediate) move
  Perform that move
  Check for win state, if so store/output it and return true.
  Call this function. If it returns true then a win state has been found so return true 
  Otherwise unperform the move
Having tried every move without finding a win state, return false.
于 2012-07-25T00:18:21.753 に答える