简体   繁体   English

为什么 return 语句不会破坏 Javascript 中的递归循环

[英]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.

相关问题 如何打破递归函数内的for循环并以Javascript返回? - How to break out of a for loop inside a recursive function and return in Javascript? return语句如何在JavaScript的递归函数中返回值? - How does return statement return values in recursive functions in JavaScript? 为什么 JavaScript 中的这个 return 语句什么都不返回? - Why does this return statement in JavaScript return nothing? 中断循环并返回值,angularJs中的递归函数 - break for loop and return value , recursive function in angularJs 为什么此递归javascript函数返回其作用? - Why does this recursive javascript function return what it does? 为什么Javascript forEach不允许使用break或return提前终止 - Why does Javascript forEach not allow early termination using break or return 为什么在javascript中向Array原型添加方法会中断for循环上的迭代? - Why does adding a method to the Array prototype in javascript break iteration on a for loop? 为什么此递归javascript函数表达式返回undefined? - Why does this recursive javascript function expression return undefined? 为什么此尾部递归循环会导致javascript / node中的堆栈溢出? - Why does this tail recursive loop cause stack overflow in javascript / node? 为什么此javascript循环会无限返回? - Why does this javascript loop return infinitely?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM