【问题标题】:javascript recursive function falling in infinite loop陷入无限循环的javascript递归函数
【发布时间】:2016-06-03 19:45:54
【问题描述】:

我有以下递归函数,除非坐标超出 DOM 表或者除非起点和当前递归点之间的距离大于用户给出的距离,否则它应该调用自己。但是函数陷入无限循环,在几个点之间无限切换,我不知道我做错了什么。

function fillSquare(a,b,dist){
    var xStart = parseInt(a);
    var yStart = parseInt(b);
    var distance = dist;

    function fill(c,d){
        var x = parseInt(c);
        var y = parseInt(d);

        if(x<0 || y<0 || x>boardWidth-1 || y>boardHeight-1){
            return;
        }else if(getDistance(cells[getFieldId(xStart,yStart)], cells[getFieldId(x,y)]) > dist){
            return;
        }else{
            cells[getFieldId(x,y)].hasWall = false;
            document.getElementById(x+'x'+y).backgroundColor = 'gray';
            console.log(x+' '+y);

            fill(x-1,y);
            fill(x+1,y);
            fill(x,y-1);
            fill(x,y+1);
        }
    }

    fill(xStart,yStart);
}

任何帮助将不胜感激。

【问题讨论】:

  • 函数中有一个函数。你的意思是这样做吗?
  • @Matt Cremeens 是的。 xStart 和 yStart 在整个过程中应该具有相同的值(因此内部填充函数可以比较起点(与坐标 xStart 和 yStart)和第 n 次递归后的点并返回它们之间的距离。我不知道如何以不同的方式做到这一点.
  • @Iven 是的,我想是的......我的目标是制作具有附加条件的洪水填充算法......
  • 看起来您可能只是在第一个 if 语句中遇到了一些错误。您是否尝试过将 -1 移至 boardWidth 和 boardHeight?
  • 我不明白 - fill(x,y+1); 将被递归 fill(x,y-1); 调用再次调用,反之亦然。有大量的多个电话。这个函数在很多方面都是错误的

标签: javascript recursion


【解决方案1】:

问题在于递归调用将返回到相同的元素。例如,当您执行fill(4, 5) 时,它会调用fill(x-1, y),即fill(3, 5)。然后调用fill(x+1, y),返回到fill(4, 5)。它将在它们之间不断循环。

你需要检查你是否已经填充了一个元素,而不是重复。

function fill(c,d){
    var x = parseInt(c);
    var y = parseInt(d);

    if(cells[getFieldId(x, y)].hasWall === false || x<0 || y<0 || x>boardWidth-1 || y>boardHeight-1){
        return;
    }else if(getDistance(cells[getFieldId(xStart,yStart)], cells[getFieldId(x,y)]) > dist){
        return;
    }else{
        cells[getFieldId(x,y)].hasWall = false;
        document.getElementById(x+'x'+y).backgroundColor = 'gray';
        console.log(x+' '+y);

        fill(x-1,y);
        fill(x+1,y);
        fill(x,y-1);
        fill(x,y+1);
    }
}

【讨论】:

    【解决方案2】:

    由于我没有您的其余代码,因此控制台输出是什么:

    // for debugging
    var i = 0;
    
    // helper function to parse into integers
    function fillSquare(xStart, yStart, distance)
    {
        // kick it off
        // on the first run the current is the start
        fill(parseInt(xStart), parseInt(yStart), parseInt(xStart), parseInt(yStart), distance);
    }
    
    function fill(xCurrent, yCurrent, xStart, yStart, distance)
    {
        // the next two lines are temporary just for debugging purposes
        ++i;
        if(i > 100) return;
    
        // log where we are so we can see progress
        console.log({ "xCurrent" : xCurrent, "yCurrent" : yCurrent, "xStart" : xStart, "yStart" : yStart, "distance" : distance, "getDistance" : getDistance(cells[getFieldId(xStart,yStart)], cells[getFieldId(xCurrent, yCurrent)]) });
    
        // no need to parse since you did that on the initial run and the recursive calls are all basic math
    
        if(xCurrent < 0 || yCurrent < 0 || xCurrent > boardWidth - 1 || yCurrent > boardHeight - 1)
        {
            return;
        }
        else if(getDistance(cells[getFieldId(xStart,yStart)], cells[getFieldId(xCurrent, yCurrent)]) > distance)
        {
            return;
        }
        else
        {
            cells[getFieldId(xCurrent,yCurrent)].hasWall = false;
            document.getElementById(xCurrent + 'x' + yCurrent).backgroundColor = 'gray';
    
            fill(xCurrent - 1, yCurrent, xStart, yStart, distance)
            fill(xCurrent + 1, yCurrent, xStart, yStart, distance)
            fill(xCurrent, yCurrent - 1, xStart, yStart, distance)
            fill(xCurrent, yCurrent + 1, xStart, yStart, distance)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      • 2021-12-17
      • 2017-03-15
      • 2023-03-17
      • 1970-01-01
      相关资源
      最近更新 更多