【问题标题】:efficient access to large collection of objects in c# [closed]在 C# 中有效访问大量对象 [关闭]
【发布时间】:2014-02-06 22:29:14
【问题描述】:

我正在使用 C# XNA 使用六边形网格制作游戏。地图大小可以是每边 6 个单元格到 144 个单元格。使用一点几何数学,这意味着最大单元格数是 61,777! (我也在考虑每边增加 216 个细胞,总共产生 139,537 个细胞!!!)

我需要的是一种基于网格坐标访问给定单元格的有效方法。 遍历整个列表,直到找到 col == c 和 row == r 的位置剪掉它。

数据结构也需要可调整大小(因为突破一个级别意味着您进入下一个地图,该地图可能更大或更小)。所以我不能使用二维数组(如果我错了,请纠正我)。现在我正在考虑 List,因为它确实有一个 ElementAt<i>。但是List<List<CELL>> 似乎很麻烦。 CELL 的动态 2D 数组似乎是最好的,但除非我严重错误,否则此类数组在 C# 中需要是固定大小的。

还请让我知道任何可能性的内部运作。列表如何存储它们的数据? (除了持有一个指针---我需要知道任何其他开销)。他们真的是随机访问还是 ElementAt<i> 实际上迭代 i 次才能到达那个元素?

我的其他激进想法就像除 base-6 之外的二叉树,例如将地图分成六边形扇区,每个扇区包含一堆单元格。然而,有了这些激进的想法,我无法理解任何实现细节:(

【问题讨论】:

  • 列表列表并不繁琐。
  • 列表将其数据存储在数组中。
  • 您也可以考虑使用Dictionary<rowKey, Dictionary<columnKey, value>>。字典的访问时间是 O(1) 基于键。 stackoverflow.com/questions/9057715/…
  • 列表也暴露了一个索引器,你不需要使用ElementAt。索引操作是 O(1),没有理由使用字典。
  • List和Dictionary访问时间比较:dotnetperls.com/dictionary-time

标签: c# xna


【解决方案1】:

您可以使用嵌套的List<List<T>>。正如其他人提到的,基于MSDN

检索此属性的值是 O(1) 操作;环境 该属性也是一个 O(1) 操作。

我建议你编写一个如下所示的接口,然后实现它,以防你以后决定更改实现。

public interface IGrid<T>
{
    T Get(int x, int y);
    void Set(int x, int y, T value);
    void Insert(int x, int y, T value);
    void Remove(int x, int y);
}

public class Grid<T>: IGrid<T>
{
    private List<List<T>> _data = new List<List<T>>();

    public T Get(int x, int y)
    {
        return _data[x][y];
    }

    public void Set(int x, int y, T value)
    {
        _data[x][y] = value;
    }

    public void Insert(int x, int y, T value)
    {
        throw new NotImplementedException();
    }

    public void Remove(int x, int y)
    {
        throw new NotImplementedException();
    }
}

然后你可以这样写:

        var myGrid = new Grid<Cell>();
        myGrid.Set(0, 0, new Cell("Blah"));

【讨论】:

    【解决方案2】:

    我会使用字典

    文档:http://msdn.microsoft.com/en-us/library/xfhwa508%28v=vs.110%29.aspx
    用法:http://www.dotnetperls.com/dictionary

    您可以使用您创建的对象(如 Point 对象)或这样的字符串对其进行索引:

    string key = r+","+c;
    

    我会选择作为字符串的键,因为这样会更容易,因为你获得的速度提升不会太多。

    考虑到您使用这样的字符串键:

    dictionary Dictionary<string,Cell> = new Dictionary<string,cell>();
    

    然后您可以创建一个创建密钥的方法,以确保您始终获得正确的密钥

    public string createKey(int row,int col)
    {
    return r+","+c;
    }
    
    public string createKey(Cell cell)
    {
    return createKey(cell.row,cell.col);
    }
    

    在检索单元格时,您会像这样调用

    int c=0;
    int r=0;
    Cell cell = dictionary[createKey(r,c)].doSomethingWithCell();
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 2016-05-11
      • 1970-01-01
      相关资源
      最近更新 更多