【问题标题】:How to fix problem in visualizing the algorithm如何解决可视化算法的问题
【发布时间】:2021-01-03 09:03:44
【问题描述】:

我想解决一个问题,我们在迷宫中找到从 (0,0) 单元格到 (m-1,n-1) 单元格的路径,中间有一些障碍。
我已经使用递归回溯算法来解决这个问题,我只是想进行某种可视化,让我们可以看到我们在迷宫中旅行时路径是如何走的。
我看到了那个问题here

现在我已经使用 javascript 实现了它,我将我们正在访问的单元格着色为蓝色,然后如果我们回溯,则再次删除颜色,但一切都发生得非常快,因为我们看不到任何事情发生,所以我尝试使用 @987654323 @ 函数有一些延迟,但我认为我没有正确使用它们,因为任何随机模式都没有显示它所采用的正确路径。

如果有人可以帮助我解决它,那将是一个很大的帮助。
你可以查看我的问题here

我的寻路算法是:

let getMazePath = async (maze, r, c, ans) => {
  if (
    r < 0 ||
    c < 0 ||
    r >= maze.length ||
    c >= maze[0].length ||
    maze[r][c] == 1 ||
    visited[r][c] == 1
  )
    return;

  if (r == maze.length - 1 && c == maze[0].length - 1) {
    document.getElementById("path-display").innerHTML =
      "Path is: '" + ans + "'";
    console.log("Path is: '" + ans + "'");
    return;
  }

  let currSq = document.getElementById(r + "_" + c);
  currSq.classList.add("visited-square");
  await sleep(1000);
  visited[r][c] = 1;

  getMazePath(maze, r - 1, c, ans + "t");
  getMazePath(maze, r, c - 1, ans + "l");
  getMazePath(maze, r + 1, c, ans + "d");
  getMazePath(maze, r, c + 1, ans + "r");

  visited[r][c] = 0;
  currSq.classList.remove("visited-square");
  await sleep(1000);
};

function sleep(ms){
  return new Promise((resolve) => {
    setTimeout(resolve, ms);
  })
}

【问题讨论】:

    标签: javascript algorithm recursion async-await backtracking


    【解决方案1】:

    您忘记等待递归调用。

    通过在 await 调用前加上前缀 getMazePath 来修复它:

    await getMazePath(maze, r - 1, c, ans + "t");
    await getMazePath(maze, r, c - 1, ans + "l");
    await getMazePath(maze, r + 1, c, ans + "d");
    await getMazePath(maze, r, c + 1, ans + "r");
    

    现场观看on CodePen


    您可能还想在它找到路径时停止它。

    为此,返回答案并检查:

    let getMazePath = async (maze, r, c, ans) => {
      if (
        r < 0 ||
        c < 0 ||
        r >= maze.length ||
        c >= maze[0].length ||
        maze[r][c] == 1 ||
        visited[r][c] == 1
      )
        return; 
    
      if (r == maze.length - 1 && c == maze[0].length - 1) {
        document.getElementById("path-display").innerHTML =
          "Path is: '" + ans + "'";
        console.log("Path is: '" + ans + "'");
        return ans;
            // ^^^
      }
    
      let currSq = document.getElementById(r + "_" + c);
      currSq.classList.add("visited-square");
      await sleep(1000);
      visited[r][c] = 1;
    
      {
        const res = await getMazePath(maze, r - 1, c, ans + "t");
        if(res) return res
      }
      {
        const res = await getMazePath(maze, r, c - 1, ans + "l");
        if(res) return res
      }
      {
        const res = await getMazePath(maze, r + 1, c, ans + "d");
        if(res) return res
      }
      {
        const res = await getMazePath(maze, r, c + 1, ans + "r");
        if(res) return res
      }
      visited[r][c] = 0;
      currSq.classList.remove("visited-square");
      await sleep(1000);
    };
    

    现场观看on CodePen

    【讨论】:

    • 你能告诉我为什么在递归调用修复它之前添加等待吗?我对异步等待了解不多。
    • @sachuverma 因为它是对 async 函数的调用。异步函数调用后立即返回,并返回一个所谓的 Promise 对象,使用它可以检查调用的状态,但是异步函数的执行是异步发生的(因此得名,对吧? )。 await 暂停异步函数的执行,直到给定的 Promise 完成。如果没有这些awaits,该函数只会启动递归调用,但不会等待它们完成。多个同时执行的函数会改变相同的对象可能会导致BIG混乱。
    猜你喜欢
    • 1970-01-01
    • 2017-10-12
    • 2011-03-20
    • 1970-01-01
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 2011-02-15
    相关资源
    最近更新 更多