2014-10-03 49 views
6

假設給出了一個整數上三角矩陣。用Java存儲這個最好的方法是什麼?天真的2d int數組顯然不高效。我提出的解決方案轉移到答案部分。用Java表示上三角矩陣的最佳數據結構是什麼?

+0

「最好」以哪種方式?靈活性?使用現有的矩陣庫之一。性能?使用普通的一維數組。 (如果性能非常關鍵並且矩陣「很小」,那麼您甚至可以考慮創建一個(rows * cols)數組並將它的左下角留空)。在任何情況下,我會遠離那些不打算用作矩陣的類(如「表」),或者來自嵌套數據結構(如list-in-lists)。還要注意,對於性能的最後一點(即使在使用數組時),*訪問模式*也是至關重要的,無論您使用的是行主或列主存儲器 – Marco13 2014-10-03 23:43:28

+0

您可以回答自己的問題:移動您的解決方案到答案(在此頁面的「答案」框中鍵入)。 – 2014-10-04 00:09:17

+0

@PeterO。謝謝。剛把它移到答案部分。 – user3639557 2014-10-04 02:09:50

回答

1

我想我找到了解決方案。這裏是我的解決方案:假設你有一個4X4的上三角矩陣M.

1 2 3 4 
0 6 7 1 
0 0 8 9 
0 0 0 5 

如果你能在一維數組M的每一個元素映射,這是最好的解決方案。所有你需要知道的是知道矩陣的哪個[行,列]對應於你的1d數組中的哪一個元素。這裏是你怎麼做的魔力:

start_index=((col_index-1)+1)+((col_index-2)+1)+...+1 
end_index=start_index + col_index 

例如:如果我想找到在哪裏都在矩陣的第三列的元素,在數組中:

start_index=((3-1)+1)+((3-2)+1)+((3-3)+1)=6 
end_index=6+3=9 

因此,所有我需要做的是從我的數組的索引6開始,讀取所有元素直到索引9(包括第9個元素)。按照這個過程,你可以在(n + n^2)/ 2空間中存儲和檢索nXn矩陣的所有單元。

1

如果矩陣始終是對角線,我會用:

List<List<Integer>> matrix = ... 

如果它是一個稀疏矩陣,我會使用地圖:

Map<Map<Integer>> = ... 

在第二種情況下,您可能需要使用get和set操作將該映射包裝到類中,以便管理對新行和列的訪問。

所有這些都取決於您的需求,您的記憶限制和矩陣大小。

+0

我制定了另一個解決方案。請看看,讓我知道你的想法。 – user3639557 2014-10-03 11:52:26

+0

@ user3639557如果你的矩陣總是三角形的,那麼你的解決方案對於內存使用來說是正確和最優的。我建議你通過它的accesors方法來實現它的包裝類,這些方法可以基於(i行,j列)索引直接訪問它的元素。 – 2014-10-03 12:18:38

2

番石榴的Table呢?它是使用HashMaps或TreeMaps(以及需要的2D數組)實現的,但它提供了比定義Map<Integer, Map<Integer, V>>更好的API。

2

如果你想節省內存,你的解決方案看起來不錯 - 它被稱爲packed storage matrix。逐列,自上而下,你的陣列應該是這樣的:1 2 6 3 7 8 4 1 9 5

我建議你指數的一個簡單的計算,基於和公式(n² + n)/2是從零開始)。

list_index = (column^2 + column)/2 + row; 

實現可能如下所示:

public class TriangularMatrix { 
    private final int[] list; 

    public TriangularMatrix(int size) { 
     list = new int[sumFormula(size)]; 
    } 

    public int set(int row, int column, int value) { 
     validateArguments(row, column); 

     int listIndex = getListIndex(row, column); 
     int oldValue = list[listIndex]; 
     list[listIndex] = value; 

     return oldValue; 
    } 

    public int get(int row, int column) { 
     validateArguments(row, column); 

     return list[getListIndex(row, column)]; 
    } 

    private void validateArguments(int row, int column) { 
     if (row > column) { 
      throw new IllegalArgumentException("Row (" + row + " given) has to be smaller or equal than column (" + column + " given)!"); 
     } 
    } 

    private int getListIndex(int row, int column) { 
     return sumFormula(column) + row; 
    } 

    private int sumFormula(int i) { 
     return (i*i + i)/2; 
    } 
} 

another question on SO討論(負)的性能影響,雖然它的Fortran。

+0

我爲上三角矩陣案例找到了解決方案,這正是我所需要的。請看看,讓我知道你的想法。 – user3639557 2014-10-03 11:56:21

+0

@ user3639557我改變了我的答案來匹配你的問題 - 我的第一個版本對三角矩陣沒有效率。 – stuXnet 2014-10-03 12:12:54

相關問題