我正在用 PHP 编写算法来解决给定的数独难题。我已经建立了一个有点面向对象的实现,它有两个类:一个Square
类用于 9x9 板上的每个单独的瓷砖,一个Sudoku
类,它有一个Square
s 矩阵来表示板。
我正在使用的算法的实现是一种三层方法。第一步,将只解决最基本的难题(但最有效),是根据棋盘的初始设置填充任何只能取单个值的方格,并相应地调整其余部分的约束未解的正方形。
通常,这种“不断传播”的过程并不能完全解决棋盘问题,但它确实解决了相当大的问题。然后第二层将启动。这会解析每个单元(或 9 个必须都具有唯一编号分配的方格,例如行或列)以获取每个未解决方格的“可能”值。此可能值列表在类中表示为字符串Square
:
class Square {
private $name; // 00, 01, 02, ... , 86, 87, 88
private $peers; // All squares in same row, col, and box
private $number; // Assigned value (0 if not assigned)
private $possibles; // String of possible numbers (1-9)
public function __construct($name, $p = 0) {
$this->name = $name;
$this->setNumber($p);
if ($p == 0) {
$this->possibles = "123456789";
}
}
// ... other functions
给定一个单元中的整个未解正方形数组(如上面第二层所述),第二层会将所有“可能”字符串连接成一个字符串。然后它将在该单个字符串中搜索任何唯一字符值 - 不会重复的值。这将表明,在方格单位内,只有一个方格可以采用该特定值。
我的问题是:为了实现第二层,我如何解析一个单元中所有可能值的字符串并轻松检测唯一值?我知道我可以创建一个数组,其中每个索引由数字 1-9 表示,并且我可以为我找到的该数字的每个可能值将相应索引处的值增加 1,然后再次扫描数组以查找任何值 1,但这似乎效率极低,需要对每个单元的数组进行两次线性扫描,而在数独游戏中有 27 个单元。