Транспонировать 1D-массив ведущего размера N

как я могу перенести 1d массив ведущего измерения N без лишнего пространства? любой язык в порядке

Ответы

Ответ 1

Мое решение для 1D транспонирования на месте матрицы

  mn    = M*N;      /* M rows and N columns */

  q     = mn - 1;

  i = 0;      /* Index of 1D array that represents the matrix */

  do {

    k = (i*M) % q;

    while (k>i) k = (M*k) % q;

    if (k!=i) Swap(k, i);

  } while ( ++i <= (mn -2) );

  /* Update row and column */

  matrix.M = N;

  matrix.N = M;

Ответ 2

Транспонирование не квадратной матрицы на месте, представленное в виде линейного массива, немного трюка.

Вот программа REXX, которая выполняет транспонирование на месте 2D-матрицу, представленную в одном мерный массив размером M * N, где M - количество строк и N - это столбцы в не транспонированный массив. После транспонирования M становится число столбцов и N становится числом строк.

i = 0                /* linear array index */ 
do j = 1 to N        /* j = 1 to columns of non-transposed array */ 
  do k = 1 to M      /* k = 1 to rows of non-transposed array */ 
    i = i + 1
    t = (k - 1) * N + j 
    do while t < i 
      jp = (t - 1) % M + 1 
      kp = t - (jp - 1) * M 
      t = (kp - 1) * N + jp 
    end 
    if i \= t then say 'exchange('i',' t')'   /* swap elements */
  end 
end

В приведенной выше программе отображаются элементы массива, которые необходимо обменять, чтобы получить транспонированный массив.

Эта программа будет работать для любого представляющую собой линейную матрицу, в которой расположены элементы по столбцу, затем строке. Например, матрица M по N будет иметь следующие элементы:

X 1,1, X 1,2,... X 1, N, X 2,1, X 2,2,... X 2, N,... X M, N

Программа печатает индексы линейных массивов элементов, которые необходимо обменять, чтобы получить транспонированная матрица вида:

X 1,1, X 2,1,... X M, 1, X 1,2, X 2,2,... X M, 2,... X M, N

Например, начните с M = 4, N = 2 и массива, содержащего:

A1, B1, A2, B2, A3, B3, A4, B4

Выполните следующие обмены:

exchange(2, 3) 
exchange(3, 5) 
exchange(4, 7) 
exchange(6, 7)

и расположение будет:

A1, A2, A3, A4, B1, B2, B3, B4

Как это работает?

Начните с обозначения, чтобы идентифицировать каждый элемент в линейном массиве как:

X[i,j,k] 

where: i is the linear array index for an element in X 
       j is the row number for element in X
       k is the column number for element in X

Используя эту нотацию, массив в строгом порядке может быть сгенерирован как:

i = 0 
do j = 1 to M    /* Row counter */ 
  do k = 1 to N  /* Column counter */ 
    i = i + 1     /* array index of element j, k */ 
    say 'X['i','j','k']' 
  end 
end

Обратите внимание, что заданные значения для j (строка) и k (столбец), i, индекс линейной матрицы для X i, j, может быть рассчитан как:

i = (j - 1) * N + k 

Транспонирование матрицы X построено путем обмена элементами X [i, j, k] с X [t, k, j] в диапазоне от j = 1 до M и k = 1 до N при условии i > t. В сущность мы обмениваем все для переменных столбца. Используя обозначение, описанное выше, это количество для обмена элементами линейного массива:

exchange(X[i,j,k], X[t,k,j])

Приведенные значения для j и k можно рассчитать значения i и t как:

   i = (j - 1) * N + k
   t = (k - 1) * M + i

Теперь перейдем к линейному массиву, сделав вышеуказанные обмены как i с 1 на M * N. Обратите внимание, что после каждой итерации все элементы X, имеющие индекс, меньший или равный i, имеют были перенесены. Это потому что каждая итерация завершается только тогда, когда правильный элемент обменивается на X [i].

Всякий раз, когда i > t, это означает, что предыдущий обмен имел место при индексе t. Элементом в t был обменивается, как указано выше, помещая его в новую позицию t prime. Учитывая index t, мы можем вычислить основной индекс строки t prime, а также строку и номера столбцов, связанные с ним, следующим образом:

j prime= (t - 1)% M + 1
k prime= t - (j prime - 1) * M
t prime= (k prime - 1) * N + j prime

Опять же, если t prime меньше i, это означает, что этот элемент был обменен и мы должны продолжать с другим циклом вычислений. Установите t в вычисленное t prime и повторите. В конце концов, i будет станет меньше t, и обмен может быть выполнен. В основном мы следуем за элементом через все его до тех пор, пока мы не найдем его в i или правее i в линейном массиве.

Повторите этот цикл для каждого элемента в линейном массиве, и матрица будет перенесена.

Ответ 3

Самый простой подход:

for each m
  for each n
    if m != n 
       swap A[m][n] and A[n][m]

Это, конечно, работает только для квадратных матриц. Для места транспонирования прямоугольных матриц все становится немного сложнее.