【问题标题】:C# List of lists issueC# 列表列表问题
【发布时间】:2011-10-12 09:42:04
【问题描述】:

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

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 个值位于矩阵的第一列,最后四个值应位于第二列。 这是动态的,因此大小不是固定的。

读取行和分隔这些行是排序的。我的问题是关于如何使用 Matrix 类来存储这些值。换句话说,我怎样才能连续处理元素?

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

0.5 10.1

0.4 11.1

0.6 0.5

0.1 12.0

提前致谢。

【问题讨论】:

  • 你已有的代码有什么问题?看起来应该可以了?
  • 问题在于添加部分。因为这是动态的,所以我不知道如何实现 matrix.Add(new List() { row elements })
  • 您已经在代码中这样做了——您的意思是同时添加多行吗?
  • 确实如此。那是我的问题。抱歉,我措辞不当。

标签: c# arrays list


【解决方案1】:

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

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; }
    }
}

或者,如果它确实需要是可变的,您可以根据需要选择“惰性”分配它:

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));
    }
}

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

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

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

【讨论】:

  • @kuzyt:我忘了在我的第一个版本中添加set 访问器。我已经更新了。
【解决方案2】:
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 } });

【讨论】:

  • 看来您可能误解了我的问题,因为我的措辞不正确。问题是我不知道正在读取的文本文件中有什么。因此矩阵的大小是动态的。
  • 您没有询问有关读取文件的问题,而是询问了列表列表以及如何将它们添加到矩阵中。您提供的解决方案和我扩展的解决方案可处理任何大小的矩阵,如有必要,不规则。 . 另一个答案,也不涉及阅读..?
【解决方案3】:

所以你想要一个接受 2 个参数、宽度和值的 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;
    }

}

【讨论】:

    猜你喜欢
    • 2011-08-03
    • 1970-01-01
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    • 2022-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多