2013-11-04 4 views
1

오늘 나는 스도쿠를 해결하는 프로그램을 작성하려고했습니다. 내 접근 방식이 제대로 작동하지 않았을 때 나는 여기에있는 해결책에 의지했습니다 : http://www.heimetli.ch/ffh/simplifiedsudoku.html재귀의 Stackoverflow 예외

하지만 어떤 이유로 인해 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

예외의 스택 추적은 무엇입니까? 그것은 당신에게 무슨 일이 일어나는지에 대한 아이디어를 줄 것입니다. 또한 코드를 디버깅하여 프로그램이 예상대로 작동하지 않는 곳을 확인하십시오. – Servy

답변

3

일예 :

내 코드입니다 여기

  return solveSudoku(row++, 0); 

row의 원래 값이 함수 solveSudoku에 전달된다 (row 그 후 증가한다). 이것을 row + 1으로 변경하십시오.

+0

고맙습니다. 불행히도 항상 작은 것들입니다. – Smoerrebroed

2

StackOverflowException의 원인은 next() 메서드 때문입니다. 이것은 적어도있는 StackOverflowException를 해결 않습니다

return solveSudoku(row, col); 

return solveSudoku(row, ++col); 

에 변경합니다. 어쨌든 알고리즘을 향상 시키려면 아직 완전한 스도쿠를 풀지 않아야합니다.