📜  C++ 数独求解器 - C++ (1)

📅  最后修改于: 2023-12-03 15:14:00.503000             🧑  作者: Mango

C++ 数独求解器

简介

本程序是一个基于C++语言实现的数独求解器,可以通过输入一个数独的初始状态,自动求解出完整的数独解。

程序使用了回溯算法搜索数独解,具有较高的求解效率和可靠性。

代码实现

程序的主要实现思路如下:

  1. 定义一个二维数组 board 来保存数独的初始状态以及最终的解。
  2. 从左到右、从上到下依次扫描数独,找到第一个没有填数字的格子(即值为0的格子)。
  3. 针对当前空格,依次尝试填入数字1~9,并判断该数字是否符合数独规则(同一行、同一列、同一宫不能有重复数字)。
  4. 如果该数字符合规则,则将该数字填入当前空格,并递归地处理下一个空格,直到所有格子全部填满为止。
  5. 如果该数字不符合规则,则回溯到上一步,并尝试填入下一个数字。
  6. 如果所有数字都尝试过了,仍然无法找到合适的数字,说明前面填的数字有误,需要回溯到上一步重新尝试其他数字。

程序的代码实现如下:

#include <iostream>
#include <vector>
using namespace std;

class Solution {
public:
    void solveSudoku(vector<vector<char>>& board) {
        if (board.empty() || board.size() != 9 || board[0].size() != 9) return;
        solve(board, 0, 0);
    }
private:
    bool solve(vector<vector<char>>& board, int i, int j) {
        if (i == 9) return true;
        if (j >= 9) return solve(board, i + 1, 0);
        if (board[i][j] != '.') return solve(board, i, j + 1);
        for (char ch = '1'; ch <= '9'; ch++) {
            if (isValid(board, i, j, ch)) {
                board[i][j] = ch;
                if (solve(board, i, j + 1)) return true;
                board[i][j] = '.';
            }
        }
        return false;
    }
    bool isValid(vector<vector<char>>& board, int i, int j, char ch) {
        for (int row = 0; row < 9; row++) {
            if (board[row][j] == ch) return false;
        }
        for (int col = 0; col < 9; col++) {
            if (board[i][col] == ch) return false;
        }
        int x = (i / 3) * 3, y = (j / 3) * 3;
        for (int row = 0; row < 3; row++) {
            for (int col = 0; col < 3; col++) {
                if (board[x + row][y + col] == ch) return false;
            }
        }
        return true;
    }
};

int main() {
    vector<vector<char>> board = {
        {'5', '3', '.', '.', '7', '.', '.', '.', '.'},
        {'6', '.', '.', '1', '9', '5', '.', '.', '.'},
        {'.', '9', '8', '.', '.', '.', '.', '6', '.'},
        {'8', '.', '.', '.', '6', '.', '.', '.', '3'},
        {'4', '.', '.', '8', '.', '3', '.', '.', '1'},
        {'7', '.', '.', '.', '2', '.', '.', '.', '6'},
        {'.', '6', '.', '.', '.', '.', '2', '8', '.'},
        {'.', '.', '.', '4', '1', '9', '.', '.', '5'},
        {'.', '.', '.', '.', '8', '.', '.', '7', '9'},
    };
    Solution().solveSudoku(board);
    for (const auto& row : board) {
        for (const auto& cell : row) {
            cout << cell << " ";
        }
        cout << endl;
    }
    return 0;
}
使用方法

本程序提供了一个简单的测试用例。运行程序,将会输出求解后的完整数独。

在代码实现中,数独的初始状态通过一个 vector<vector<char>> 类型的变量 board 来表示,其中'.'字符表示空格,数字字符表示已填数字。

程序的求解过程通过一个递归函数 solve 来实现,函数参数包括当前处理的行号 i 和列号 j,以及表示数独状态的二维数组 board。函数的返回值为一个布尔值,表示是否找到了正确的解。

程序主函数中,首先定义了一个初始数独状态,然后调用 solveSudoku 函数对其进行求解,并将求解后的结果输出到控制台上。

总结

本程序实现了一个高效的数独求解器,并提供了一个简单的测试用例供程序员参考。程序的重点在于使用回溯算法进行搜索,通过逐个枚举每个空格可能填入的数字并判断其是否符合数独规则,最终找到一个符合要求的完整解。