Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C#中创建和管理类似于列表对象的二维数组?_C#_Arrays_List - Fatal编程技术网

如何在C#中创建和管理类似于列表对象的二维数组?

如何在C#中创建和管理类似于列表对象的二维数组?,c#,arrays,list,C#,Arrays,List,我需要一个二维阵列,它可以在所有方向上扩展,并严格跟踪每个元素的整体定位,但在读取时效率最高 用例I面如下所示: 我正在碰撞二维构造板块,并将其相互挤压。当它们碰撞时,它们可以收缩、生长,或者两者都不能。每次迭代,所有元素都可能被访问,所以读取时间非常重要。它们也必须能够在所有侧面上生长/收缩,并且可以包含孔和凸面结构 记忆不是一个大问题,但我想把它保存在我能保存的地方。我主要关心的是速度,因为旧的概念证明,这是松散的基于C++编写的,需要15分钟运行,并且我大大增加了原来的概念。 我最初想到用

我需要一个二维阵列,它可以在所有方向上扩展,并严格跟踪每个元素的整体定位,但在读取时效率最高

用例I面如下所示: 我正在碰撞二维构造板块,并将其相互挤压。当它们碰撞时,它们可以收缩、生长,或者两者都不能。每次迭代,所有元素都可能被访问,所以读取时间非常重要。它们也必须能够在所有侧面上生长/收缩,并且可以包含孔和凸面结构

记忆不是一个大问题,但我想把它保存在我能保存的地方。我主要关心的是速度,因为旧的概念证明,这是松散的基于C++编写的,需要15分钟运行,并且我大大增加了原来的概念。
我最初想到用坐标字典,但这就带来了阅读时间的问题;当请求一些他们没有密钥的东西时,字典的速度很慢,这种情况经常发生

我现在正在考虑使用
列表
结构,对空位置使用空类对象

我的另一个想法是使用代数数组(y*stride+x),但我更愿意避免其复杂性,而且它很难构建和维护

那么,从本质上讲,拥有一个在C#中不断访问和频繁修改的非常大的2D数据集的最佳方式是什么

编辑: 应要求; 每个阵列可能在50x50和1000x1000之间,并且在任何给定时间都有10-30个阵列。整个“世界”的大小为512x512到4096x4096(在模拟开始时设置),最大重叠约为20%(不包括边缘情况)。然而,在笛卡尔坐标系中,每个2D板中有多达50%的空间是空的,因此在尺寸一致的情况下,这意味着阵列的实际尺寸将是最多约20132659个非空阵列元素的两倍,并且略小于模拟中空阵列元素总数的两倍


我同意这个程序需要几个小时才能完成sim卡,但我担心这需要几天的时间。这就是为什么我试图找到处理这些数据集的最佳方法。

这取决于你如何阅读你的收藏

例如,如果在每个元素之间循环,那么列表总是比字典快

List<List<Item>> collection = new List<List<Items>>();
//add items
for(List l : collection){
 for(Item i : l){
   //do something with item
 }
}
列表集合=新列表();
//添加项目
对于(列表l:集合){
用于(项目i:l){
//对这个项目做些什么
}
}
如果您正在根据“key”值查找索引,那么字典将总是更快(常数vs线性)

Dictionary collection=newdictionary();
//添加项目
List keysWeNeedToWorkOn=新列表();
//添加我们关心的密钥
for(字符串键:键WENEEDTOWORKON){
用于(项目i:收集。获取(关键)){
//用这个东西做点什么
}
}

这可能有助于您准确地决定您需要什么。

这取决于您阅读收藏的方式

例如,如果在每个元素之间循环,那么列表总是比字典快

List<List<Item>> collection = new List<List<Items>>();
//add items
for(List l : collection){
 for(Item i : l){
   //do something with item
 }
}
列表集合=新列表();
//添加项目
对于(列表l:集合){
用于(项目i:l){
//对这个项目做些什么
}
}
如果您正在根据“key”值查找索引,那么字典将总是更快(常数vs线性)

Dictionary collection=newdictionary();
//添加项目
List keysWeNeedToWorkOn=新列表();
//添加我们关心的密钥
for(字符串键:键WENEEDTOWORKON){
用于(项目i:收集。获取(关键)){
//用这个东西做点什么
}
}

<>这可能有助于你准确地确定你需要什么。

如果你坚持有一个可扩展的2D数组(矩阵),那么考虑以下内容:

public class Matrix<T> : Collection<T>
{
    int row_count, col_count;
    List<T> _list; //reference to inner list
    T[] _items; //reference to inner array within inner list

    public Matrix(int row_count, int col_count)
        : this(row_count, col_count, new T[row_count*col_count])
    {
        if(row_count==0||col_count==0)
        {
            throw new NotSupportedException();
        }
    }

    Matrix(int row_count, int col_count, T[] values)
        : base(new List<T>(values))
    {
        // internal data arranged in 1D array, by rows.
        this._list=base.Items as List<T>;
        this.row_count=row_count;
        this.col_count=col_count;
        LinkInnerArray();
    }

    private void LinkInnerArray()
    {
        this._items=typeof(List<T>).GetField("_items",
            System.Reflection.BindingFlags.NonPublic
            |System.Reflection.BindingFlags.Instance).GetValue(base.Items) as T[];
    }

    public int RowCount { get { return row_count; } }
    public int ColCount { get { return col_count; } }
    public T[] Elements { get { return _list.ToArray(); } }

    public T this[int row, int col]
    {
        get { return base[col_count*row+col]; }
        set { base[col_count*row+col]=value; }
    }

    public T[] GetRow(int row)
    {
        if(row<0||row>=row_count) new IndexOutOfRangeException();
        T[] result=new T[col_count];
        lock(_items)
        {
            // fast array copy
            Array.Copy(_items, col_count*row, result, 0, result.Length);
        }
        return result;
    }
    public T[] GetColumn(int column)
    {
        if(column<0||column>=col_count) new IndexOutOfRangeException();
        T[] result=new T[row_count];
        lock(_items)
        {
            // No shortcut exists, only if C# was more like FORTRAN
            for(int i=0; i<row_count; i++)
            {
                result[i]=base[col_count*i+column];
            }
        }
        return result;
    }
    public void SetRow(int row, params T[] values)
    {
        if(values==null||values.Length==0) return;
        if(row<0||row>=row_count) new IndexOutOfRangeException();
        // fast array copy
        lock(_items)
        {
            Array.Copy(values, 0, _items, col_count*row, values.Length);
        }
    }
    public void SetColumn(int column, params T[] values)
    {
        if(values==null||values.Length==0) return;
        if(column<0||column>=col_count) new IndexOutOfRangeException();
        lock(_items)
        {
            // No shortcut exists, only if C# was more like FORTRAN
            for(int i=0; i<values.Length; i++)
            {
                base[col_count*i+column]=values[i];
            }
        }
    }

    public void AddRow(params T[] new_row)
    {
        lock(_list)
        {
            // add array to last row
            T[] row=new T[col_count];
            Array.Copy(new_row, 0, row, 0, new_row.Length);
            _list.AddRange(row);
            LinkInnerArray();
            this.row_count++;
        }
    }

    public void AddColumn(params T[] new_column)
    {
        lock(_list)
        {
            // go add an item on end of each row
            for(int i=row_count-1; i>=0; i--)
            {
                T item=i<new_column.Length?new_column[i]:default(T);
                _list.Insert(col_count*i+row_count-1, item);
            }
            LinkInnerArray();
            this.col_count++;
        }
    }

    public Matrix<R> Transform<R>(Func<T, R> operation)
    {
        R[] values=new R[row_count*col_count];
        for(int i=0; i<values.Length; i++)
        {
            values[i]=operation(base[i]);
        }
        return new Matrix<R>(row_count, col_count, values);
    }

    public Matrix<R> Combine<R>(Matrix<T> other, Func<T, T, R> operation)
    {
        R[] values=new R[row_count*col_count];
        for(int i=0; i<values.Length; i++)
        {
            values[i]=operation(base[i], other[i]);
        }
        return new Matrix<R>(row_count, col_count, values);
    }
}

class Program
{
    static void Main(string[] args)
    {
        int N=4;
        var A=new Matrix<int>(N, N);
        // initialize diagonal
        for(int i=0; i<N; i++)
        {
            A[i, i]=1;
        }

        // A = 
        // | 1  0  0  0 |
        // | 0  1  0  0 |
        // | 0  0  1  0 |
        // | 0  0  0  1 |

        A.AddRow(5, 4, 3, 2);
        A.AddColumn(1, 2, 3, 4, 5);

        // A = 
        // | 1  0  0  0  1 |
        // | 0  1  0  0  2 |
        // | 0  0  1  0  3 |
        // | 0  0  0  1  4 |
        // | 5  4  3  2  5 |

        var B=A.Transform(delegate(int x) { return 5-x; });
        // B = 
        // | 4  5  5  5  4 |
        // | 5  4  5  5  3 |
        // | 5  5  4  5  2 |
        // | 5  5  5  4  1 |
        // | 0  1  2  3  0 |

        var C=A.Combine(B, delegate(int x, int y) { return y-x; });
        // C = 
        // | 3  5  5  5  3 |
        // | 5  3  5  5  1 |
        // | 5  5  3  5 -1 |
        // | 5  5  5  3 -3 |
        // |-5 -3 -1  1 -5 |
    }
}
公共类矩阵:集合
{
int行计数、列计数;
List _List;//对内部列表的引用
T[]\u items;//对内部列表中的内部数组的引用
公共矩阵(整数行计数、整数列计数)
:此(行计数、列计数、新T[行计数*列计数])
{
如果(行计数=0 |列计数=0)
{
抛出新的NotSupportedException();
}
}
矩阵(整数行计数、整数列计数、T[]值)
:基本(新列表(值))
{
//内部数据按行排列在1D数组中。
此._list=base.Items作为列表;
这个。row\u count=row\u count;
this.col\u count=col\u count;
LinkInnerArray();
}
私有void linkinnerray()
{
此.\u items=typeof(List).GetField(“\u items”,
System.Reflection.BindingFlags.NonPublic
|GetValue(base.Items)作为T[];
}
public int RowCount{get{return row_count;}}
public int ColCount{get{return col_count;}}
公共T[]元素{get{return}list.ToArray();}
公共T此[int行,int列]
{
获取{return base[col_count*行+列];}
设置{base[col_count*行+列]=value;}
}
公共T[]获取行(int行)
{
if(row=row_count)new IndexOutOfRangeException();
T[]结果=新的T[col_count];
锁定(_项)
{
//快速阵列拷贝
数组.Copy(_items,col_count*行,result,0,result.Length);
}
返回结果;
}
公共T[]GetColumn(int列)
{
if(column=col_count)new IndexOutOfRangeException();
T[]结果=新的T[行数];
锁定(_项)
{
//只有在C#更像FORTRAN的情况下,才不存在捷径

对于(int i=0;i)如果你坚持有一个可扩展的2D数组(矩阵),那么考虑以下内容:

public class Matrix<T> : Collection<T>
{
    int row_count, col_count;
    List<T> _list; //reference to inner list
    T[] _items; //reference to inner array within inner list

    public Matrix(int row_count, int col_count)
        : this(row_count, col_count, new T[row_count*col_count])
    {
        if(row_count==0||col_count==0)
        {
            throw new NotSupportedException();
        }
    }

    Matrix(int row_count, int col_count, T[] values)
        : base(new List<T>(values))
    {
        // internal data arranged in 1D array, by rows.
        this._list=base.Items as List<T>;
        this.row_count=row_count;
        this.col_count=col_count;
        LinkInnerArray();
    }

    private void LinkInnerArray()
    {
        this._items=typeof(List<T>).GetField("_items",
            System.Reflection.BindingFlags.NonPublic
            |System.Reflection.BindingFlags.Instance).GetValue(base.Items) as T[];
    }

    public int RowCount { get { return row_count; } }
    public int ColCount { get { return col_count; } }
    public T[] Elements { get { return _list.ToArray(); } }

    public T this[int row, int col]
    {
        get { return base[col_count*row+col]; }
        set { base[col_count*row+col]=value; }
    }

    public T[] GetRow(int row)
    {
        if(row<0||row>=row_count) new IndexOutOfRangeException();
        T[] result=new T[col_count];
        lock(_items)
        {
            // fast array copy
            Array.Copy(_items, col_count*row, result, 0, result.Length);
        }
        return result;
    }
    public T[] GetColumn(int column)
    {
        if(column<0||column>=col_count) new IndexOutOfRangeException();
        T[] result=new T[row_count];
        lock(_items)
        {
            // No shortcut exists, only if C# was more like FORTRAN
            for(int i=0; i<row_count; i++)
            {
                result[i]=base[col_count*i+column];
            }
        }
        return result;
    }
    public void SetRow(int row, params T[] values)
    {
        if(values==null||values.Length==0) return;
        if(row<0||row>=row_count) new IndexOutOfRangeException();
        // fast array copy
        lock(_items)
        {
            Array.Copy(values, 0, _items, col_count*row, values.Length);
        }
    }
    public void SetColumn(int column, params T[] values)
    {
        if(values==null||values.Length==0) return;
        if(column<0||column>=col_count) new IndexOutOfRangeException();
        lock(_items)
        {
            // No shortcut exists, only if C# was more like FORTRAN
            for(int i=0; i<values.Length; i++)
            {
                base[col_count*i+column]=values[i];
            }
        }
    }

    public void AddRow(params T[] new_row)
    {
        lock(_list)
        {
            // add array to last row
            T[] row=new T[col_count];
            Array.Copy(new_row, 0, row, 0, new_row.Length);
            _list.AddRange(row);
            LinkInnerArray();
            this.row_count++;
        }
    }

    public void AddColumn(params T[] new_column)
    {
        lock(_list)
        {
            // go add an item on end of each row
            for(int i=row_count-1; i>=0; i--)
            {
                T item=i<new_column.Length?new_column[i]:default(T);
                _list.Insert(col_count*i+row_count-1, item);
            }
            LinkInnerArray();
            this.col_count++;
        }
    }

    public Matrix<R> Transform<R>(Func<T, R> operation)
    {
        R[] values=new R[row_count*col_count];
        for(int i=0; i<values.Length; i++)
        {
            values[i]=operation(base[i]);
        }
        return new Matrix<R>(row_count, col_count, values);
    }

    public Matrix<R> Combine<R>(Matrix<T> other, Func<T, T, R> operation)
    {
        R[] values=new R[row_count*col_count];
        for(int i=0; i<values.Length; i++)
        {
            values[i]=operation(base[i], other[i]);
        }
        return new Matrix<R>(row_count, col_count, values);
    }
}

class Program
{
    static void Main(string[] args)
    {
        int N=4;
        var A=new Matrix<int>(N, N);
        // initialize diagonal
        for(int i=0; i<N; i++)
        {
            A[i, i]=1;
        }

        // A = 
        // | 1  0  0  0 |
        // | 0  1  0  0 |
        // | 0  0  1  0 |
        // | 0  0  0  1 |

        A.AddRow(5, 4, 3, 2);
        A.AddColumn(1, 2, 3, 4, 5);

        // A = 
        // | 1  0  0  0  1 |
        // | 0  1  0  0  2 |
        // | 0  0  1  0  3 |
        // | 0  0  0  1  4 |
        // | 5  4  3  2  5 |

        var B=A.Transform(delegate(int x) { return 5-x; });
        // B = 
        // | 4  5  5  5  4 |
        // | 5  4  5  5  3 |
        // | 5  5  4  5  2 |
        // | 5  5  5  4  1 |
        // | 0  1  2  3  0 |

        var C=A.Combine(B, delegate(int x, int y) { return y-x; });
        // C = 
        // | 3  5  5  5  3 |
        // | 5  3  5  5  1 |
        // | 5  5  3  5 -1 |
        // | 5  5  5  3 -3 |
        // |-5 -3 -1  1 -5 |
    }
}
公共类矩阵:集合
{
int行计数、列计数;
List _List;//对内部列表的引用
T[]\u items;//对内部列表中的内部数组的引用
公共矩阵(整数行计数、整数列计数)
:此(行计数、列计数、新T[行计数*列计数])
{
我