sudoku

    技术2022-05-19  18

    #include <iostream>

    #include <stack>

    #include <vector>

    // function main use arry to initialize a sudoku game.

    // You can use 0 to take instead of any number in the array.

    // recompile the cpp use command: g++ -o sudoku sudoku.cpp

    // Then run it use commond: ./sudoku.

     

    using std::stack;

    using std::vector;

    using namespace std;

     

    const int SUDOKU_COLS = 3;

    const int SUDOKU_ROWS = 3;

    const int SUDOKU_DIMS = SUDOKU_COLS * SUDOKU_ROWS;

     

    class CSudoku

    {

    public:

    CSudoku(){}

    CSudoku(int array[][9]);

    void next_step(vector<CSudoku>&);

    bool have_finished() const;

    friend ostream& operator << (ostream &os, const CSudoku &s);

    friend istream& operator >> (istream &is, CSudoku &s);

    private:

    int cell[SUDOKU_DIMS][SUDOKU_DIMS];

    void fill_number(bool pos[], const int width, bool value);

    static void dispose_number(bool *pos, int i)

    {

    if (i != 0)

    {

    pos[i - 1] = false;

    }

    }

    };

     

    CSudoku::CSudoku(int array[][9])

    {

    for (int r = 0; r < SUDOKU_DIMS; r++)

    for (int c = 0; c < SUDOKU_DIMS; c++)

    cell[r][c] = array[r][c];

    }

     

    void CSudoku::fill_number(bool pos[], const int width, bool value)

    {

    for (int i = 0; i < width; i++)

    pos[i] = true;

    }

     

    ostream &operator << (ostream &os, const CSudoku &s)

    {

    for (int i = 0; i < SUDOKU_DIMS; i++)

    {

    for (int j = 0; j < SUDOKU_DIMS; j++)

    {

    os << s.cell[i][j] << " ";

    }

    os << endl;

    }

    return os;

    }

    istream &operator >> (istream &is, CSudoku &ps)

    {

    int v;

    for (int r = 0; r < SUDOKU_DIMS; r++)

    {

    for (int c = 0; c < SUDOKU_DIMS; c++)

    {

    is >> v;

    ps.cell[r][c] = (v < 1 || v > 9) ? 0 : v;

    }

    }

    return is;

    }

    bool print_result(const CSudoku &s)

    {

    cout << "CSudoku answer:/n" << s << endl;

    return true;

    }

     

    bool CSudoku::have_finished() const

    {

    for (int row = 0; row < SUDOKU_DIMS; row++)

    {

    for (int column = 0; column < SUDOKU_DIMS; column++)

    {

    if (cell[row][column] == 0)

    return false;

    }

    }

    return true;

    }

    void CSudoku::next_step(vector<CSudoku>& vs)

    {

    CSudoku sdk;

     

    bool pos[SUDOKU_DIMS];

     

    for (int row = 0; row < SUDOKU_DIMS; row++)

    {

    for (int column = 0; column < SUDOKU_DIMS; column++)

    {

    if (cell[row][column] == 0)

    {

    fill_number(pos, SUDOKU_DIMS, true);

    for (int i = 0; i < SUDOKU_DIMS; i++)

    {

    dispose_number(pos, cell[i][column]);

    dispose_number(pos, cell[row][i]);

    }

    int lr = row - (row % SUDOKU_ROWS);

    int lc = column - (column % SUDOKU_COLS);

     

    for (int i = 0; i < SUDOKU_ROWS; i++)

    {

    for (int j = 0; j < SUDOKU_COLS; j++)

    {

    dispose_number(pos, cell[lr + i][lc + j]);

    }

    }

    for (int i = 0; i < SUDOKU_DIMS; i++)

    {

    if (pos[i])

    {

    sdk = *this;

    sdk.cell[row][column] = i + 1;

    vs.push_back(sdk);

    }

    }

    return;

    }

    }

    }

    }

     

    template <class T1, class T2>

    int depth_first_search(const T1 &init_state, const T2 &after_find_solution)

    {

    int n = 0;

    stack<T1> states;

     

    states.push(init_state);

     

    vector<T1> next_states;

    bool stop = false;

     

    while (!stop && !states.empty())

    {

    T1 s = states.top();

    states.pop();

    next_states.clear();

    s.next_step(next_states);

    for (typename vector<T1>::iterator i = next_states.begin(); i != next_states.end(); ++i)

    {

    if (i->have_finished())

    {

    ++n;

    if (after_find_solution(*i))

    {

    stop = true;

    break;

    }

    }

    else

    {

    states.push(*i);

    }

    }

    }

    return n;

    }

     

    int main(int argc, char **argv)

    {

    int array[9][9] = {

    {3,1,7,4,6,9,8,2,5},

    {4,5,6,2,8,7,3,1,9},

    {9,2,8,3,1,5,7,4,6},

    {2,8,5,6,4,3,9,7,1},

    {6,4,1,7,9,8,5,3,2},

    {7,3,9,5,2,1,4,6,8},

    {1,7,2,8,5,4,6,9,3},

    {8,6,3,9,7,2,1,5,4},

    {5,9,4,1,3,6,2,8,7},

    };

    CSudoku sudo(array);

     

    if (argc != 1)

    cin >> sudo;

    cout << "Question:/n" << sudo << endl;

     

    int n = depth_first_search(sudo, &print_result);

     

    if (n == 0)

    {

    cout << "Solution not found!" << endl;

    }

    else

    {

    cout << n << " solution(s) found!/n" << endl;

    }

    return 0;

     

    }


    最新回复(0)