javascript - 我的 javascript 暴力递归数独解算器是否内存不足?

标签 javascript memory recursion sudoku

我编写了一个 JavaScript 程序来解决数独问题。它似乎正在工作,但突然停止了。 Console shows that it is working but suddenly stops for no reason

是这个原因吗? : (Timeline)我是 JavaScript 新手,我能做些什么来修复它?

我该如何解决这个问题?谢谢!

这是代码:

<html>

<head>
</head>

<body>
  <script>
    var game = [
      [0, 0, 9, 0, 5, 7, 0, 6, 0],
      [0, 7, 0, 6, 0, 0, 0, 0, 0],
      [8, 0, 0, 0, 1, 0, 7, 5, 0],
      [0, 0, 0, 3, 6, 0, 1, 7, 2],
      [4, 1, 2, 0, 0, 0, 6, 9, 3],
      [6, 3, 7, 0, 2, 9, 0, 0, 0],
      [0, 4, 1, 0, 5, 0, 0, 0, 7],
      [0, 0, 0, 0, 0, 3, 0, 8, 0],
      [0, 5, 0, 2, 9, 0, 4, 0, 0]
    ];

    function solve(x, y, g) {
      var nextx;
      var nexty = y;
      if (x < 9 || y < 9) {
        if (g[x][y] == 0) {
          for (i = 1; i < 10; i++) {
            g[x][y] = i;
            if (check(x, y, i, g) == true) {
              if (x < 8) {
                nextx = x + 1;
              } else {
                nexty = y + 1;
                nextx = 0;
              }
              console.log(x + ' ' + y + ' ' + i + ' ' + g[x][y]);
              solve(nextx, nexty, g);
            } else {
              if (x != 0 && y != 0) {
                return;
              }
            }
          }
        } else {
          if (x < 8) {
            nextx = x + 1;
          } else {
            nexty = y + 1;
            nextx = 0;
          }
          console.log(x + ' ' + y + ' ' + 'b' + ' ' + g[x][y]);
          solve(nextx, nexty, g);
          return;
        }
      } else {
        if (checkall(g) == true) {
          for (var i = 0; i < 9; i++) {
            document.write(g[i] + '</br>');
          };
        } else {
          document.write("can't solve");
        }
      }
    }

    function check(x, y, i, g) {
      var tempx = 0;
      var tempy = 0;
      var tempb = 0;
      var a, b;

      for (j = 0; j < 9; j++) {
        if (g[x][j] == i) {
          tempx = tempx + 1;
        }
        if (g[j][y] == i) {
          tempy = tempy + 1;
        }
      }

      if (x < 3) {
        a = 0;
      }
      if (x < 6) {
        a = 3;
      }
      if (x < 9) {
        a = 6;
      }
      if (y < 3) {
        b = 0;
      }
      if (y < 6) {
        b = 3;
      }
      if (y < 9) {
        b = 6;
      }

      for (c = a; c < a + 3; c++) {
        for (d = b; d < b + 3; d++) {
          if (g[a][b] == i) {
            tempb = tempb + 1;
          }
        }
      }

      if (tempx > 1 || tempy > 1 || tempb > 1) {
        return false;
      } else {
        return true;
      }

    }

    function checkall(g) {
      var temp1 = 0;
      var temp2 = 0;
      for (var i = 0; i < 10; i++) {
        for (var x = 0; x < 9; x++) {
          for (var y = 0; y < 9; y++) {
            if (g[x][y] == i) {
              temp1 = temp1 + 1;
            }
            if (g[y][x] == i) {
              temp2 = temp2 + 1;
            }
          };
          if (temp1 > 1 || temp2 > 1) {
            return false;
          } else {
            temp1 = 0;
            temp2 = 0;
          }
        }
      }
      return true
    }

    solve(0, 0, game);
  </script>
  </div>
</body>

</html>

最佳答案

确保检查从函数返回的响应:

    var div = document.getElementById('output');

将会失败,div 将“未定义”,因为您的示例中没有带有“输出”id 的开始 div 标记。

如果您向函数添加 try/catch 子句,您将看到报告的错误。

我可以看到您实际上并没有在代码中使用“div”。

我刚刚稍微修改了您的代码,因为运行它时没有收到任何错误:

    <html>
    <body>
      <script>
        var game = [
          [0, 0, 9, 0, 5, 7, 0, 6, 0],
          [0, 7, 0, 6, 0, 0, 0, 0, 0],
          [8, 0, 0, 0, 1, 0, 7, 5, 0],
          [0, 0, 0, 3, 6, 0, 1, 7, 2],
          [4, 1, 2, 0, 0, 0, 6, 9, 3],
          [6, 3, 7, 0, 2, 9, 0, 0, 0],
          [0, 4, 1, 0, 5, 0, 0, 0, 7],
          [0, 0, 0, 0, 0, 3, 0, 8, 0],
          [0, 5, 0, 2, 9, 0, 4, 0, 0]
        ];
        var intNestedCalls = 0;
        function solve(x, y, g) {
          var nextx;
          var nexty = y;
          intNestedCalls++; //Count numer of nested calls
          if (x < 9 || y < 9) {
            if (g[x][y] == 0) {
              for (i = 1; i < 10; i++) {
                g[x][y] = i;
                if (check(x, y, i, g) == true) {
                  if (x < 8) {
                    nextx = x + 1;
                  } else {
                    nexty = y + 1;
                    nextx = 0;
                  }
                  console.log(x + ' ' + y + ' ' + i + ' ' + g[x][y]);
                  solve(nextx, nexty, g);
                } else {
                  if (x != 0 && y != 0) {
    //Break here so we drop out and exit the function              
                    break;
                  }
                }
              }
            } else {
              if (x < 8) {
                nextx = x + 1;
              } else {
                nexty = y + 1;
                nextx = 0;
              }
              console.log(x + ' ' + y + ' ' + 'b' + ' ' + g[x][y]);
              solve(nextx, nexty, g);
    //No need to return here, fall through and exit normally
    //        return;                  
            }
          } else {
            if (checkall(g) == true) {
              for (var i = 0; i < 9; i++) {
                document.write(g[i] + '</br>');
              };
            } else {
              document.write("can't solve");
            }
          }
          intNestedCalls--; //Update nested call counter
        }
        function check(x, y, i, g) {
          var tempx = 0;
          var tempy = 0;
          var tempb = 0;
          var a, b;
          for (j = 0; j < 9; j++) {
            if (g[x][j] == i) {
              tempx = tempx + 1;
            }
            if (g[j][y] == i) {
              tempy = tempy + 1;
            }
          }
          if (x < 3) {
            a = 0;
          }
          if (x < 6) {
            a = 3;
          }
          if (x < 9) {
            a = 6;
          }
          if (y < 3) {
            b = 0;
          }
          if (y < 6) {
            b = 3;
          }
          if (y < 9) {
            b = 6;
          }
          for (c = a; c < a + 3; c++) {
            for (d = b; d < b + 3; d++) {
              if (g[a][b] == i) {
                tempb = tempb + 1;
              }
            }
          }
          if (tempx > 1 || tempy > 1 || tempb > 1) {
            return false;
          } else {
            return true;
          }
        }
        function checkall(g) {
          var temp1 = 0;
          var temp2 = 0;
          for (var i = 0; i < 10; i++) {
            for (var x = 0; x < 9; x++) {
              for (var y = 0; y < 9; y++) {
                if (g[x][y] == i) {
                  temp1 = temp1 + 1;
                }
                if (g[y][x] == i) {
                  temp2 = temp2 + 1;
                }
              };
              if (temp1 > 1 || temp2 > 1) {
                return false;
              } else {
                temp1 = 0;
                temp2 = 0;
              }
            }
          }
          return true;
        }
        solve(0, 0, game);    
    alert("Complete!");    
      </script>
      </div>
    </body>
    </html>

除了完整的输出之外,我根本看不到任何输出!短时间后发出警报。

逻辑永远不会到达您的“document.write”指令,因为 x 和 y 只有在 x AND y >= 9 时您的逻辑才会到达 write 语句。

您的测试应该是:

    if ( x < 9 && y < 9 ) {

关于javascript - 我的 javascript 暴力递归数独解算器是否内存不足?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36057402/

相关文章:

c++ - 函数返回错误值

javascript - node.js request.get 用 html 正文响应,忽略 404 状态

javascript - Angular:根据服务方法调用设置路由

c++ - 从偏移创建一个 DWORD 指针

javascript - 使用 JavaScript 交换 DOM 元素,用于内存密集型应用程序

c# - 如何使用c#中的程序检查堆栈内存的大小

python - Python 中数组的递归问题

javascript - 如何检查一个 JSON 对象是否存在于另一个对象中

javascript - 如果它有值,则将 html 输入框设置为只读

java - 递归方法将字符串中的每个字母向后打印 3 次