
数独游戏的核心规则之一是确保每个数字在特定区域内(行、列、3x3宫格)只能出现一次。在编写数独校验器时,一个常见的辅助函数是includes1to9,其目标是验证一个给定的数字数组是否满足这些唯一性要求。然而,这个函数的实现往往容易出错,导致校验器无法正确识别无效的数独布局。
在提供的数独校验代码中,includes1To9 函数的原始实现如下:
function includes1To9(arr) {
let prev = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i] === prev) return false; // 仅检查当前元素与前一个元素
prev = arr[i];
}
return true;
}问题所在: 此函数的逻辑缺陷在于它只检查当前元素 arr[i] 是否与其紧邻的前一个元素 prev 相同。这种方法无法检测数组中非相邻的重复数字。例如,对于数组 [1, 2, 1, 4, 5, 6, 7, 8, 9],按照数独规则,它包含重复的数字 1,因此应该返回 false。然而,上述函数会错误地返回 true,因为它在遍历过程中,arr[i] (第二个 1) 与 prev (即 2) 并不相等,导致它误判为没有重复。
正是这种逻辑漏洞,使得数独校验器在面对某些包含非相邻重复数字的无效数独时,无法正确返回 false,从而导致测试失败。
JavaScript 中的 Set 是一种非常有用的数据结构,它只存储唯一的值。我们可以利用 Set 的这个特性来高效地检测数组中是否存在重复元素。
Set 的工作原理: 当你将一个数组传递给 Set 的构造函数时,Set 会自动过滤掉所有重复的元素,只保留唯一的值。因此,如果一个数组中的所有元素都是唯一的,那么由该数组创建的 Set 的大小将与原始数组的长度相等。反之,如果 Set 的大小小于原始数组的长度,则说明数组中存在重复元素。
优化的 includes1To9 函数:
立即学习“Java免费学习笔记(深入)”;
function includes1To9(arr) {
// 创建一个Set,它会自动去除数组中的重复元素
const uniqueElements = new Set(arr);
// 如果Set的大小与原始数组的长度相同,则表示没有重复元素
return uniqueElements.size === arr.length;
}示例验证:
console.log(includes1To9([1, 2, 1, 4, 5, 6, 7, 8, 9])); // 输出: false (正确,因为1重复) console.log(includes1To9([1, 2, 2, 4, 5, 6, 7, 8, 9])); // 输出: false (正确,因为2重复) console.log(includes1To9([1, 2, 3, 4, 5, 6, 7, 8, 9])); // 输出: true (正确,无重复)
通过将 includes1To9 函数替换为上述 Set 实现,数独校验器将能够准确地检测到所有类型的重复数字,从而解决之前测试失败的问题。
sudokuIsValid 函数是整个数独校验器的核心,它依赖于 getRow、getColumn、getSection 等辅助函数来提取数独的各个部分,并使用 includes1To9 来验证这些部分的有效性。
function sudokuIsValid(puzzle) {
// 检查所有3x3宫格的有效性
for (let x = 0; x < 3; x++) {
for (let y = 0; y < 3; y++) {
if (includes1To9(getSection(puzzle, x, y)) === false) return false;
}
}
// 检查所有行和列的有效性
for (let i = 0; i < puzzle.length; i++) {
if (includes1To9(getRow(puzzle, i)) === false) return false;
if (includes1To9(getColumn(puzzle, i)) === false) return false;
}
return true; // 所有检查通过,数独有效
}将优化后的 includes1To9 函数集成到 sudokuIsValid 中后,整个数独校验器将变得更加健壮和准确。
虽然 Set 方法能有效解决重复元素检测的问题,但对于一个完整的数独校验,includes1To9 函数的职责可能不仅仅是检查唯一性。数独规则要求每个区域(行、列、3x3宫格)必须:
如果输入数组可能包含少于9个数字、超出1-9范围的数字(如0或10),或者非数字类型,那么仅仅依靠 Set 的唯一性检查是不够的。
一个更健壮的 includes1To9 函数应该同时检查这些条件:
function includes1To9(arr) {
// 1. 检查数组长度是否为9
if (arr.length !== 9) {
return false;
}
// 2. 使用Set检查数字的唯一性
const uniqueElements = new Set(arr);
if (uniqueElements.size !== 9) {
return false; // 存在重复数字
}
// 3. 检查所有数字是否都在1到9的范围内
for (const num of arr) {
// 确保是数字类型,并且在1到9之间
if (typeof num !== 'number' || num < 1 || num > 9) {
return false; // 存在非数字或超出范围的数字
}
}
return true; // 通过所有检查
}这个增强版的 includes1To9 函数提供了更全面的验证,能够处理更广泛的潜在无效输入,从而使数独校验器更加可靠。
数独校验器中的重复元素检测是其核心功能之一。通过将原始的、仅检查相邻元素的 includes1To9 函数替换为利用 JavaScript Set 数据结构的高效去重方法,可以显著提高校验器的准确性和健壮性。进一步,结合对数组长度和数字范围的检查,可以构建一个全面且可靠的 includes1To9 函数,确保数独在所有维度上都符合规则。在开发过程中,编写全面的测试用例是不可或缺的实践,它能帮助我们及早发现并修复潜在的逻辑错误。
以上就是优化JavaScript数独校验器:高效检测重复元素的策略的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号