[英]why does return statement not break recursive for loop in Javascript
Please i am trying to build a Sudoku solver in JavaScript but i face a problem when i get to the solve function , the recursive loop doesn't stop when the board is full.请我尝试在 JavaScript 中构建数独求解器,但是当我解决 function时遇到问题,当电路板已满时递归循环不会停止。 It executes till the end even after finding the solution.
即使找到解决方案,它也会执行到最后。 Please I'll be grateful if i can get some help.
如果我能得到一些帮助,我将不胜感激。 Here is what i tried doing:
这是我尝试做的事情:
class SudokuSolver {
// convert puzzle string to 2D array
boardParser(puzzleString) {
var board = [];
var i, j;
for (i = 0; i < 81; i += 9) {
var boardRow = [];
for (j = 0; j < 9; j++) {
boardRow.push(puzzleString.charAt(i + j));
}
board.push(boardRow)
}
// console.log(board);
return board;
}
// Look for empty space on board (empty space = ".")
// return [row, col] if empty space found
// return [-1,-1] if no empty space found (board is full)
getDot(board) {
var i, j;
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
if (board[i][j] == ".") {
return [i, j];
}
}
}
return [-1, -1];
}
checkRowPlacement(board, row, column, value) {
var i;
for (i = 0; i < 9; i++) {
if (board[row][i] == value) {
// console.log("row check false");
return {
valid: false
};
}
}
// console.log("row check true");
return {
valid: true
}
}
checkColPlacement(board, row, column, value) {
var i;
for (i = 0; i < 9; i++) {
if (board[i][column] == value) {
// console.log("col check false")
return {
valid: false
}
}
}
// console.log("col check true")
return {
valid: true
};
}
checkRegionPlacement(board, row, column, value) {
var i, j;
var regRow = Math.floor(row / 3) * 3;
var regCol = Math.floor(column / 3) * 3;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
if (board[regRow + i][regCol + j] == value) {
// console.log("reg check false")
return {
valid: false
}
}
}
}
// console.log("reg check true");
return {
valid: true
}
}
checkvalue(board, row, column, value) {
var rowCheck = this.checkRowPlacement(board, row, column, value).valid
var colCheck = this.checkColPlacement(board, row, column, value).valid
var regCheck = this.checkRegionPlacement(board, row, column, value).valid
// console.log(rowCheck, colCheck, regCheck);
if (rowCheck && colCheck && regCheck) {
// console.log(true)
return true;
}
// console.log(false)
return false;
}
// convert 2D array back to string
stringifyBoard(board) {
var string = ""
var i, j;
for (i = 0; i < 9; i++) {
for (j = 0; j < 9; j++) {
string += board[i][j];
}
}
// console.log(string);
return string;
}
// check for any more empty spaces
solved(board) {
var i, j;
if (this.getDot(board)[0] == -1) {
return true
}
return false
}
solve(puzzleString) {
var board = this.boardParser(puzzleString)
var emptySpot = this.getDot(board);
var row = emptySpot[0];
var column = emptySpot[1];
// full board condition
if (this.solved(board)) {
return puzzleString;
}
for (var i = 1; i <= 9; i++) {
if (this.checkvalue(board, row, column, i)) {
board[row][column] = i;
var boardString = this.stringifyBoard(board);
this.solve(boardString);
}
}
// if board is unsolvable return false
return false;
}
}
const input = '5..91372.3...8.5.9.9.25..8.68.47.23...95..46.7.4.....5.2.......4..8916..85.72...3';
console.log(new SudokuSolver().solve(input));
it returns false, but the puzzle string is valid and also when i console log in the full board condition it shows the solved string but doesn't return it.它返回false,但拼图字符串是有效的,而且当我控制台登录全板条件时,它显示已解决的字符串但不返回它。
So once the board is solved and if this.solved(board) returns true, you are returning the solved board.因此,一旦解决了棋盘并且如果 this.solved(board) 返回 true,则您将返回已解决的棋盘。 But this is only at the last level of recursion chain.
但这只是递归链的最后一层。 You need to check at every level of recursion if this particular move reaches a solved board state.
如果此特定移动到达已解决的板 state,您需要检查每个递归级别。 Hence, validate the result of the next level and if it returns a solved board, return the solved board from the current level too.
因此,验证下一个级别的结果,如果它返回一个已解决的板,则也从当前级别返回已解决的板。 I have made appropriate changes in the solve function-
我已经对求解功能进行了适当的更改-
solve(puzzleString) {
var board = this.boardParser(puzzleString)
var emptySpot = this.getDot(board);
var row = emptySpot[0];
var column = emptySpot[1];
// full board condition
if (this.solved(board)) {
return puzzleString;
}
for (var i = 1; i <= 9; i++) {
if (this.checkvalue(board, row, column, i)) {
board[row][column] = i;
var boardString = this.stringifyBoard(board);
var result = this.solve(boardString);
if(result !== false){
return result;
}
}
}
// if board is unsolvable return false
return false;
}
for (var i = 1; i <= 9; i++) {
if (this.checkvalue(board, row, column, i)) {
board[row][column] = i;
var boardString = this.stringifyBoard(board);
if(this.solve(boardString)) return true; //I've a modification here
}
}
You didn't write any code to stop the function when the solution is found.当找到解决方案时,您没有编写任何代码来停止 function。 Here is my solution:
这是我的解决方案:
for (var i = 1; i <= 9; i++) {
if (this.checkvalue(board, row, column, i)) {
board[row][column] = i;
var boardString = this.stringifyBoard(board);
var sol = this.solve(boardString); // change
if (sol) return sol // change
}
}
I have done a similar one in python a while ago.不久前,我在 python 中做过类似的事情。 Check it here if you are interested: https://onlinegdb.com/SJt2PQrjP
如果您有兴趣,请在此处查看: https://onlinegdb.com/SJt2PQrjP
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.