递归中的Stackoverflow异常

时间:2013-11-04 15:53:50

标签: c# recursion sudoku stack-overflow

今天我想写一个解决数独的程序。 当我的方法不起作用时,我使用了一个解决方案:http://www.heimetli.ch/ffh/simplifiedsudoku.html

但出于某种原因,我不断收到StackOverflow异常。

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Sudoku_Solver
{
class Program
{
    static void Main(string[] args)
    {
        MainClass _mainClass = new MainClass();

        _mainClass.printSudoku();

        Console.ReadLine();
    }
}

class MainClass
{
    private const int FieldsVertical = 3, FieldsHorizontal = 3;
    private const int RowsInField = 3, ColumnsInField = 3;

    Thread _sudokuSolverThread;

    private int[,] Sudoko = new int[(FieldsVertical * ColumnsInField), (FieldsHorizontal * RowsInField)]{
        { 4, 0, 2, 0, 3, 0, 0, 0, 0},
        { 7, 0, 8, 0, 4, 2, 0, 9, 0},
        { 0, 0, 0, 8, 0, 5, 4, 0, 0},
        { 0, 8, 0, 0, 0, 4, 2, 0, 9},
        { 0, 9, 4, 2, 0, 6, 8, 1, 0},
        { 6, 0, 1, 7, 0, 0, 0, 3, 0},
        { 0, 0, 9, 5, 0, 3, 0, 0, 0},
        { 0, 3, 0, 4, 6, 0, 7, 0, 2},
        { 0, 0, 0, 0, 2, 0, 9, 0, 3},
    };

    public MainClass(){ }

    private void startSudokuSolver()
    {
        solveSudoku(0, 0);
    }

    private bool solveSudoku(int row, int col)
    {
        if (Sudoko[row, col] != 0)
        {
            return next(row, col++);
        }
        else
        {
            for (int i = 0; i < ColumnsInField * RowsInField; i++)
            {
                if (checkColumn(i, row) && checkField(i, row, col) && checkRow(i, col))
                {
                    Sudoko[row, col] = i;

                    //Thread.Sleep(10);

                    return next(row, col++);
                }
            }
            Sudoko[row, col] = 0;

            return false;
        }
    }

    private bool next(int row, int col)
    {
        if (row == 9)
        {
            return false;
        }
        else
        {
            if (col == 9)
            {
                return solveSudoku(row++, 0);
            }
            else
            {
                return solveSudoku(row, col);
            }
        }
    }

    public void printSudoku()
    {
        startSudokuSolver();

        for (int i = 0; i < Sudoko.GetLength(0); i++)
        {
            for (int x = 0; x < Sudoko.GetLength(1); x++)
            {
                Console.Write(Sudoko[i, x] + " ");
            }
            Console.Write(Environment.NewLine);
        }
    }

    private bool checkRow(int number, int col)
    {
        for (int row = 0; row < FieldsVertical * RowsInField; row++)
        {
            if (Sudoko[row, col] == number)
            {
                return false;
            }
        }

        return true;
    }

    private bool checkColumn(int number, int row)
    {
        for (int column = 0; column < FieldsHorizontal * ColumnsInField; column++)
        {
            if (Sudoko[row, column] == number)
            {
                return false;
            }
        }
        return true;
    }

    int _currentFieldRow;
    int _currentFieldColumn;

    private bool checkField(int number, int row, int col)
    {
        _currentFieldRow = (row / RowsInField) * RowsInField;
        _currentFieldColumn = (col / ColumnsInField) * ColumnsInField;

        for (int a = _currentFieldRow; a < _currentFieldRow + RowsInField; a++)
        {
            for (int b = _currentFieldColumn; b < _currentFieldColumn + ColumnsInField; b++)
            {
                if (Sudoko[a, b] == number)
                {
                    return false;
                }
            }
        }
        return true;
    }
}

}

2 个答案:

答案 0 :(得分:3)

E.g。这里

            return solveSudoku(row++, 0);

row的原始值传递给函数solveSudoku(之后row递增)。将其更改为row + 1

答案 1 :(得分:2)

StackOverflowException的原因在next()方法中。变化

return solveSudoku(row, col);

return solveSudoku(row, ++col);

这至少解决了StackOverflowException。无论如何,你需要进一步增强算法,因为它还没有解决完整的数独。