【问题标题】:Identifying connecting elements in an array识别数组中的连接元素
【发布时间】:2012-12-20 19:01:48
【问题描述】:

所以我试图解决这个问题的是给定一个数字网格,我希望在网格中有一个偶数的位置,通过这个位置,它会找到所有其他连接到它的偶数元素。

这张图片显示了我想要描述的内容。图片假设我有 6 的位置

这是我写的代码我几乎可以肯定它可以工作我只是想看看是否有任何方法可以提高效率

getLinksEven(grid,0,1);
static void getLinksEven(Server[][] grid, int k, int j)
{
    try{
        if(grid[k-1][j].isEven()&& !grid[k-1][j].isCracked()){
            grid[k-1][j].setCracked(true);
            getLinksEven(grid,k-1,j);
        }

    }
    catch(ArrayIndexOutOfBoundsException a)
    {
        //do nothing
    }
    try{
        if(grid[k][j-1].isEven()&& !grid[k][j-1].isCracked()){
            grid[k][j-1].setCracked(true);
            getLinksEven(grid,k,j-1);

        }

    }
    catch(ArrayIndexOutOfBoundsException a)
    {
        //do nothing
    }

    try{
        if(grid[k+1][j].isEven()&& !grid[k+1][j].isCracked()){
            grid[k+1][j].setCracked(true);
            getLinksEven(grid,k+1,j);

        }

    }
    catch(ArrayIndexOutOfBoundsException a)
    {
        //do nothing
    }
    try{
        if(grid[k][j+1].isEven()&& !grid[k][j+1].isCracked()){
            grid[k][j+1].setCracked(true);
            getLinksEven(grid,k,j+1);

        }

    }
    catch(ArrayIndexOutOfBoundsException a)
    {
        //do nothing
    }

}

【问题讨论】:

  • (我认为如果 6 在 1,2 而不是 0,1 会更直观)
  • @cwallenpoole,计算机科学中的几乎一切都使用基于 0 的索引。使用基于 1 的索引将直观。
  • @SimonC 目前,他从左上角开始为 0,0,右下角为 2,2(这就是他使用 0,1 表示 6 的原因)。相反,右下角应该是 0,0。这将使 6 在第二个 x 索引 (1) 和第三个 y 索引 (2) 处。现在,您可以尝试争辩说它应该像我们定位像素而不是像我们定位坐标系那样来定位,但我不相信这一点。
  • @SimonC 另外,如果 0, 1 是 6,那么这意味着他正在订购他的数字 y,x。这显然违反了大多数标准做法。
  • @cwallenpoole,我的错,我以为你指的是索引的基数。使用 x 和 y 作为变量名会更直观,然后先传递 x。但是,我认为说 0,0 是否应该是右下角是有争议的。我明白为什么底部 left 可能更有意义。

标签: java performance recursion multidimensional-array


【解决方案1】:

我认为您正在测试不需要测试的节点:。我会看到每个方向有四个函数:

// you'll need four methods just like this one. This one goes up, you'll need
// one that goes down, another left and a forth right...
static void iterUp(Server[][] grid, int k, int j)
{
    // working with a local variable is easier to read and debug...
    // you may wish to consider it.
    Server cell = grid[k][j]
    if(!cell.isEven() && !cell.isCracked())
    {
        cell.setCracked(true)
        if(k >= 1)
        {
            iterLeft(grid, k-1,j)
        }
        if(k < grid.length - 2)
        {
            iterRight(grid, k+1)
        }
        if(j < grid[k].length - 2)
        {
            iterUp(grid, k, j+1)
        }
        // no point in going down, because we know that down is checked already.
    }
}

然后我会定义原来的函数:

static void getLinksEven(Server[][] grid, int k, int j)
{
    if(grid.length < k - 1 || grid[k].length < j - 1)
    {
        throw new ArrayIndexOutOfBoundsException("Not funny.");
    }
    // if this cell isn't even... who cares?
    if(!grid[k][j].isEven()) return;

    // Send the four on their merry way.
    iterUp(grid,k,j);
    iterDown(grid,k,j);
    iterLeft(grid,k,j);
    iterRight(grid,k,j);
}

这将为您节省至少 1/4 次数组查找,并可能节省对 isEven()isCracked() 的调用次数。

【讨论】:

  • 我不确定我是否理解代码。因为你有和 iterDown() iterLeft() 和和 iterRight() 方法,但它们都没有被定义。另外我们怎么知道 down 已经被检查了?
  • left right 和 down 就像 up 一样,只是它们会向左、向右和向下移动。
  • 您会知道下面的节点已经被检查过,因为 up 方法只会向上迭代(这意味着它 必须 已从已在其下方检查过的节点调用)。
  • 当我把它提交到我应该的地方它仍然说它运行得太慢了。你认为有更快的非递归解决方案吗?
  • @WillJamieson 你试过用数字迭代吗?这样可以节省时间。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-04
  • 1970-01-01
  • 2011-11-03
  • 2020-02-22
  • 1970-01-01
  • 2014-08-27
  • 1970-01-01
相关资源
最近更新 更多