2011-10-12 89 views
2

我有另一个清单列表的问题。再次,我有如下的通用矩阵类。C#列表清单问题

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

我读从包含具有以下格式值的文本文件串的线,

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

预先感谢。

+0

您已有的代码有什么问题?它看起来应该工作? –

+0

问题在于添加部分。因为这是动态的,我不知道如何实现矩阵。添加(新列表(){行元素}) – nixgadgets

+0

你已经在代码中做到了这一点 - 你的意思是在同一时间添加多行?确实是 –

回答

1

如果您的矩阵尺寸真的是可变的?一个更好的替代方法可能是通过内部构造的尺寸和分配阵列矩阵内:

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

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

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

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

+0

非常感谢。我明白你的意思了! – nixgadgets

+0

@kuzyt:我忘了在第一次修订中添加'set'访问器。我已经更新了它。 – Groo

0

所以你需要一个具有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; 
    } 

} 
+0

任何意见去反对投票? – Jodrell

1
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 } }); 
+0

似乎你可能误解了我的问题,因为我没有正确地使用它。问题是我不知道正在读取的文本文件中有什么。因此矩阵的大小是动态的。 – nixgadgets

+0

你没有询问关于阅读文件的问题,你询问了关于列表清单以及如何将它们添加到矩阵中......你给出的解决方案,我扩大了与任何大小矩阵的交易,如果有必要,不规则..其他答案,吨处理阅读要么..? –