我有一个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
}
这比我现在的性能好很多,但我想知道是否有更简单的方法来实现这一目标?这看起来有点凌乱,我觉得有一种方法可以在一行中做到这一点,但我只是无法弄清楚数学。
编辑:抱歉,我可能省略了一些重要细节。与“邻居”变量一起使用的代码被遗漏了,因为它很长并且对解决方案没有帮助。我不需要维护一个“邻居”变量列表(这就是我目前正在做的事情,它使用了太多的内存(大约400megs)。我只需要一个快速的方法来查看每个项目,找到每个相邻的8个项目,一次一个地做一些事情,然后移动到下一个节点。上面的代码将通过它们,但它不是最优化的方法来实现它。
答案 0 :(得分:1)
看起来您实际上是在3D数据结构中给定深度处的2D阵列中找到邻居。即你忽略了相邻深处的邻居。
你的方法可能非常有效。你可以找到一些更低级的打字方式,例如this answer关于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];
}
}
}
}