2014-10-03 83 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

相关问题