假设给出了一个整数的上三角矩阵。什么是在Java中存储它的最佳方式?天真的2d int数组显然效率不高。我提出的解决方案已转移到答案部分。
答案 0 :(得分:3)
如果你想节省内存,你的解决方案看起来很棒 - 它被称为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有关。
答案 1 :(得分:2)
番石榴Table
怎么样?它使用HashMaps或TreeMaps(以及必要时的2D数组)实现,但它提供了比定义Map<Integer, Map<Integer, V>>
更好的API。
答案 2 :(得分:1)
如果矩阵总是对角线,我会使用:
List<List<Integer>> matrix = ...
如果是稀疏矩阵,我会使用map:
Map<Map<Integer>> = ...
在第二种情况下,您可能需要使用get和set操作将地图包装在一个类中,以便管理对新行和列的访问。
所有这些都取决于您的需求,记忆限制和矩阵大小。
答案 3 :(得分:1)
我想我找到了解决方案。这是我的解决方案:假设您有一个4X4上三角矩阵M。
1 2 3 4
0 6 7 1
0 0 8 9
0 0 0 5
如果您可以在1d数组中映射M的每个元素,那么这是最好的解决方案。您需要知道的是知道哪个[row,col]矩阵对应于1d数组的哪个元素。以下是你如何做到这一点:
start_index=((col_index-1)+1)+((col_index-2)+1)+...+1
end_index=start_index + col_index
例如:如果我想找到矩阵的第3列上的元素在数组中:
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矩阵的所有单元格。