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
提前谢谢。
您的矩阵维度真的应该是可变的吗?一个更好的选择可能是在构造函数中传递其维度,并在矩阵中分配数组:
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;
}
}