Какова наилучшая структура данных для представления верхней треугольной матрицы в Java?
предположим, что задана верхняя треугольная матрица целых чисел. Каков наилучший способ хранения этого на Java? Наивный 2D int массив, очевидно, не эффективен. Решение, которое я придумал, было перенесено в раздел ответов.
4 ответов
Как насчет гуавы Table
? Он реализован с использованием HashMaps или TreeMaps (а также 2D-массива, если требуется), но он предлагает гораздо более приятный API, чем определение Map<Integer, Map<Integer, V>>
.
если вы хотите сохранить память, ваше решение выглядит здорово - это называется упакованная матрица хранения. По столбцам, сверху-вниз, Ваш массив будет выглядеть так: 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;
}
}
здесь еще один вопрос так обсуждение (отрицательного) влияния на производительность, хотя речь идет о Fortran.
если матрица всегда диагональна, я бы использовал:
List<List<Integer>> matrix = ...
Если это разреженная матрица, я бы использовал карты:
Map<Map<Integer>> = ...
во втором случае может потребоваться обернуть карту в класс с операциями get и set для управления доступом к новым строкам и столбцам.
все это, однако, зависит от ваших потребностей, ограничений памяти и размера матрицы.
Я думаю, что нашел решение. Вот мое решение: Предположим, у вас есть верхняя треугольная матрица 4X4 M.
1 2 3 4
0 6 7 1
0 0 8 9
0 0 0 5
Если вы можете отобразить каждый элемент M в массиве 1d, это лучшее решение. Все, что вам нужно знать-это знать, что [строка,колонка] матрицы соответствует элементу массива 1д. Вот как вы делаете магию:
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-й элемент). Следуя этой процедуре, вы можете сохранить и получить все ячейки матрицы nXn в (n + n^2)/2 пространстве.