2011-10-12 122 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

你沒有詢問關於閱讀文件的問題,你詢問了關於列表清單以及如何將它們添加到矩陣中......你給出的解決方案,我擴大了與任何大小矩陣的交易,如果有必要,不規則..其他答案,噸處理閱讀要麼..? –