0

我有一个 3D 列表(3 个嵌套列表),对于列表中的每个项目,我需要找到相邻的项目。目前,我正在为每个相邻项目创建一个数组,并将其存储在每个项目中。这是相当资源密集型的,所以我希望稍微简化一下。

我正在考虑使用这种方法:

for (int i = 0; i < 8; i++)
{
    switch (i)
    {
        case (0):
            mapCell neighbor = myMap.Depth[z].Rows[x].Columns[y - 1];
        case (1):
            mapCell neighbor = myMap.Depth[z].Rows[x].Columns[y + 1];
        case (2):
            mapCell neighbor = myMap.Depth[z].Rows[x - 1].Columns[y];
        case (3):
            mapCell neighbor = myMap.Depth[z].Rows[x + 1].Columns[y];
        case (4):
            mapCell neighbor = myMap.Depth[z].Rows[x + 1].Columns[y + 1];
        case (5):
            mapCell neighbor = myMap.Depth[z].Rows[x + 1].Columns[y - 1];
        case (6):
            mapCell neighbor = myMap.Depth[z].Rows[x - 1].Columns[y + 1];
        case (7):
            mapCell neighbor = myMap.Depth[z].Rows[x - 1].Columns[y - 1];
    }

    // do some stuff with the neighbor here
}

就性能而言,这比我现在拥有的要好得多,但我想知道是否有更简单的方法来实现这一点?看起来有点乱,我真的觉得有一种方法可以在 1 行中做到这一点,但我就是无法弄清楚数学。

编辑:对不起,我可能遗漏了一些重要的细节。与“邻居”变量一起使用的代码已被忽略,因为它很长并且对解决方案没有帮助。我不需要维护“邻居”变量的列表(这就是我目前正在做的事情,它使用了太多的内存(大约 400 兆)。我只需要一种快速的方法来查看每个项目,找到每个相邻的 8 个项目,一次对它们做一些事情,然后移动到下一个节点。上面的代码可以通过它们,但感觉不是最优化的方法。

4

1 回答 1

1

看起来您实际上是在 3D 数据结构中给定深度的 2D 数组中找到邻居。即,您忽略了相邻深度的邻居。

您的方法可能非常有效。您可以找到一些涉及更少打字的更奇特的方式,例如this answer to a similar question on SO,但我怀疑它会更快。

显然,您还需要在代码中包含一些检查,以处理不会有 8 个邻居的边缘项目。

private void DoSomethingWithNeighbours(int x, int y, int z)
{
    foreach (var neighbout in this.GetNeighbours(x, y, z)
    {
        // ...
    }
}

private IEnumerable<Item> GetNeighbours(int x, int y, int z)
{
    if (x > 0)
    {
        if (y > 0)
        {
            yield return myMap.Depth[z].Rows[x - 1].Columns[y - 1];
        }

        yield return myMap.Depth[z].Rows[x - 1].Columns[y];

        if (y < ColumnCount - 1)
        {
            yield return myMap.Depth[z].Rows[x - 1].Columns[y + 1];
        }
    }

    if (y > 0)
    {
        yield return myMap.Depth[z].Rows[x].Columns[y - 1];
    }

    if (y < ColumnCount - 1)
    {
        yield return myMap.Depth[z].Rows[x].Columns[y + 1];
    }

    if (x < RowCount - 1)
    {
        if (y > 0)
        {
            yield return myMap.Depth[z].Rows[x + 1].Columns[y - 1];
        }

        yield return myMap.Depth[z].Rows[x + 1].Columns[y];

        if (y < ColumnCount - 1)
        {
            yield return myMap.Depth[z].Rows[x + 1].Columns[y + 1];
        }
    }
}

或者以下更简洁的替代方案,只有边际性能成本:

private IEnumerable<int> GetNeighbours2(int x, int y, int z)
{
    for (int i = x - 1; i <= x + 1; ++i)
    {
        for (int j = y - 1; j <= y + 1; ++j)
        {
            if (i >= 0 && i < Rows && j >= 0 && j < Cols && !(i == x && j == y))
            {
                yield return myMap.Depth[z].Rows[i].Columns[j];
            }
        }
    }
}
于 2013-01-16T01:34:27.823 回答