c++使用列表解决数独

C++ using lists to solve sudoku

本文关键字:解决 列表 c++      更新时间:2023-10-16

我正在尝试在c++中制作一个数独求解器。我想保存一个从[9]到[9]的数组(很明显)。我现在在想一个方法来记录可能的值。我想为数组中的每个元素创建一个列表。所以这个列表一开始是从1到9的数字,每次迭代我都可以去掉一些值。

现在我的问题是,我可以为2D数组中的每个条目分配一个列表吗?如果可以,如何分配?还有其他/更好的选择吗?

我是一个初学者,这基本上是我用c++的第一个项目。提前感谢!

一个简单的解决方案是为每个正方形使用一组位标志,例如

uint16_t board[9][9]; // 16 x 1 bit flags for each square where 9 bits are used
                      // to represent possible values for the square

然后你可以使用位运算符来设置/清除/测试每个位,例如

board[i][j] |= (1 << n);  // set bit n at board position i, j
board[i][j] &= ~(1 << n); // clear bit n at board position i, j
test = (board[i][j] & (1 << n)) != 0; // test bit n at board position i, j

你可以通过

创建一个集合数组
std::array<std::set<int>,81> possibleValues;
例如

。您可以通过写入

来填充该数组的所有可能性。
const auto allPossible = std::set<int>{ 0, 1, 2, 3, 4, 5, 6, 7, 8 };
std::fill( std::begin(possibleValues), std::end(possibleValues), 
    allPossible );

如果您使用的是现代c++ 11编译器。下面是设置/清除和测试每个条目的方法:

possibleValues[x+9*y].insert( n ); // sets that n is possible at (x,y).
possibleValues[x+9*y].erase( n ); // clears the possibility of having n at (x,y).
possibleValues[x+9*y].count( n ) != 0 // tells, if n is possible at (x,y).

如果性能是一个问题,您可能希望使用位操作而不是(相对)重量级的std::set操作。在这种情况下使用

std::array<short, 81> possibleValues;
std::fill( begin(possibleValues), end(possibleValues), (1<<10)-1 );

(x,y)字段取值n当且仅当possibleValues[x+9*y] & (1<<n) != 0,在这种情况下所有索引都从0开始。

你可以把你的数独想象成一个3D数组,让你的3D维度来存储可能的值,主要是:

// set "1" in cell's which index corespond to a possible value for the Sudoku cell
for (int x = 0; x < 9; x++)
    for (int y = 0; y < 9; y++)
        for (int i = 1; i < 10; i++)
            arr[x][y][i] = 1;

arr[x][y][0]包含您的数独值。

例如,

要删除作为单元格[x][y]的可能性的值"5"只需更改arr[x][y][5] = 0

的值