Преобразование диагонали матрицы в рваный массив? - PullRequest
3 голосов
/ 13 марта 2009

Я пытаюсь придумать не грубое решение следующей проблемы. Дана матрица произвольного размера:

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

Преобразуйте свои диагонали в список векторов, например:

(0)
(1, 2)
(3, 4, 5)
(6, 7, 8, 9)
(0, 1, 2)
(3, 4)
(5)

(в этом примере работает слева направо и снизу вверх)

Есть ли элегантный способ сделать это, если перебрать левый столбец и перебрать верхний ряд?

Ответы [ 3 ]

2 голосов
/ 13 марта 2009

Я бы просто написал небольшую функцию для преобразования векторных индексов в матричные индексы.

Скажем, матрица NxN квадратная, тогда будет 2N-1 векторов; если мы нумеруем векторы от 0 до 2N-2, элемент k вектора n будет находиться в строке max(N-1-n+k,k) и столбце max(n+k-N+1,k) (или наоборот, элемент матрицы в строке i, столбец j будет элементом min(i,j) вектора N-1+j-i). Тогда всякий раз, когда вам нужно получить доступ к элементу вектора, просто преобразуйте координаты из k,n в i,j (то есть преобразовайте векторные индексы в матричные индексы) и получите доступ к соответствующему элементу матрицы. Вместо того, чтобы фактически иметь список векторов, вы получите нечто, что эмулирует список векторов, в том смысле, что оно может дать вам любой желаемый элемент любого вектора в списке - что на самом деле так же хорошо. (Добро пожаловать на утку печатать; -)

Если вы собираетесь получить доступ к каждому элементу матрицы, возможно, вам будет проще выполнить итерацию, а не делать это каждый раз.

1 голос
/ 13 марта 2009

(не проверенный код) Примерно так (код Java):

// suppose m is the matrix, so basically an int[][] array with r rows and c columns
// m is an int[rows][cols];

List result = new ArrayList(rows + cols - 1);
for (int i = 0; i < (rows + cols - 1))
{
  int y;
  int x;
  if (i < rows)
  {
    x = 0;
    y = rows - i - 1;
  }
  else
  {
    x = i - rows + 1;
    y = 0;
  }
  Vector v = new Vector();
  while (y < rows && x < cols)
  {
    y++;
    x++;
    v.add(new Integer(m[y][c]));
  }
  result.add(v);
}
// result now contains the vectors you wanted

Редактировать: Я перепутал x и y, исправлено.

0 голосов
/ 13 марта 2009

Mathematica:

m = {{6, 0, 3, 5}, 
     {3, 7, 1, 4}, 
     {1, 4, 8, 2}, 
     {0, 2, 5, 9}};

Table[Diagonal[m, i], {i, 1 - Length@m, Length@m[[1]] - 1}]

, который дает список i-й диагонали, где 0-я диагональ является главной диагональю, i = -1 дает нижнюю диагональ и т. Д. Другими словами, возвращается:

{{0}, {1, 2}, {3, 4, 5}, {6, 7, 8, 9}, {0, 1, 2}, {3, 4}, {5}}

Конечно, использование встроенной функции Diagonal - это обман. Вот реализация Diagonal с нуля:

(* Grab the diagonal starting from element (i,j). *)
diag0[m_,i_,j_] := Table[m[[i+k, j+k]], {k, 0, Min[Length[m]-i, Length@m[[1]]-j]}]

(* The i'th diagonal -- negative means below the main diagonal, positive above. *)
Diagonal[m_, i_] := If[i < 0, diag0[m, 1-i, 1], diag0[m, 1, i+1]]

Функция Table в основном представляет собой цикл for, который собирается в список. Например,

Table[2*i, {i, 1, 5}]

возвращает {2,4,6,8,10}.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...