C#列表发布

本文关键字:列表 | 更新日期: 2023-09-27 18:10:58

我还有一个关于列表列表的问题。再一次,我有一个通用矩阵类,如下所示。

public class Matrix<T>
{
  List<List<T>> matrix;
  public Matrix()
  {
     matrix = new List<List<T>>();
  }
  public void Add(IEnumerable<T> row)
  {
     List<T> newRow = new List<T>(row);
     matrix.Add(newRow);
  }
}
// Test code
Matrix<double> matrix = new Matrix<double>();    
matrix.Add(new List<double>() { 0, 0 });
matrix.Add(new List<double>() { 16.0, 4.0 });

我正在从一个文本文件中读取字符串行,该文件包含以下格式的值,

4 2

0.5 0.4 0.6 0.1 10.1 11.1 0.5 12.0

第一行指定4x2矩阵大小。第二行需要使得前4个值在矩阵的第一列中,最后4个值应该在第二列中。这是动态的,因此大小不是固定的。

读取行并对这些行进行定界是经过排序的。我的问题是如何使用Matrix类来存储这些值。换言之,我该如何处理一行中的元素?

应该这样做,使矩阵看起来像

0.5 10.1

0.4 11.1

0.6 0.5

0.1 12.0

提前谢谢。

C#列表发布

您的矩阵维度真的应该是可变的吗?一个更好的选择可能是在构造函数中传递其维度,并在矩阵中分配数组

public class Matrix<T>
{
    private readonly T[][] _matrix;
    public Matrix(int rows, int cols)
    {
        _matrix = new T[rows][];
        for (int r = 0; r < rows; r++)
            _matrix[r] = new T[cols];
    }
    public T this[int r, int c]
    {
        get { return _matrix[r][c]; }
        set { _matrix[r][c] = value; }
    }
}

或者,如果it确实需要是可变的,您可以根据需要选择将其分配为"惰性":

public class Matrix<T>
{
    private readonly List<List<T>> _matrix;
    public Matrix()
    {
        _matrix = new List<List<T>>();
    }
    public T this[int r, int c]
    {
        get
        {
            ResizeIfNeeded(r, c);
            return _matrix[r][c]; 
        }
        set
        {
            ResizeIfNeeded(r, c);
            _matrix[r][c] = value;
        }
    }
    private void ResizeIfNeeded(int row, int col)
    {
        while (_matrix.Count <= r)
            _matrix.Add(new List<T>());
        var row = _matrix[r];
        while (row.Count <= c)
            row.Add(default(T));
    }
}

请注意,如果按顺序填充,第二种方法可能会进行大量分配。

我会选择第一种方法(一个固定大小的矩阵(,因为在大多数情况下,它的维度是已知的。它的分配速度最快,在多线程应用程序中使用也很安全。

如果您正在从文件中读取值,那么通过索引设置它们应该比为每一行实例化一个新列表简单得多。

public void AddRange(IEnumerable<List<T>> rows)
{
    foreach (var row in rows)
    {
        Add(row);
    }
}

然后:

AddRange(new List<double>[] {
   new List<double> { 0.0, 0.0 },
   new List<double> { 16.0, 14.0 } });

所以我们想要一个具有两个参数,宽度和值的ctor。

public Matrix(int width, IEnumerable<T> values)
{
    if (values.Count() % width != 0)
        throw new ArgumentException("values parameter is indivisible by width");
    int last = 0;
    for (int i = width; i <= values.Count(); i += width)
    {
        Add(values.Skip(last).Take(width))
        last = i;
    }
}