一种简单的原地转置方式是从矩阵的后面开始将每个元素旋转到位。您只需要每次将一个单独的元素旋转到位,因此对于示例,从[0,1,2,3,4,5,6,7,8,9,a,b]
开始,您可以得到:
0,1,2,3,4,5,6,7,8,9,a,b, // step 0
,b, // step 1
,8,9,a,7, // step 2
4,5,6,8,9,a,3, // step 3
,a, // step 4
,8,9,6, // step 5
,4,5,8,9,2, // step 6
,9, // step 7
,8,5, // step 8
,4,8,1, // step 9
,8, // step 10
,4, // step 11
0, // step 12
(这只是显示每一步中元素旋转到最终位置的过程。)
如果你按照每个元素要旋转多少次来写出来(从后往前),它会形成一个很好的进展。例如(width=4
,height=3
):
1,4,7,1,3,5,1,2,3,1,1,1
1,4,7,
1,3,5,
1,2,3,
1,1,1
1个元素的旋转实际上没有任何作用,但是该过程导致了非常简单的算法(使用C++编写):
void transpose(int *matrix, int width, int height)
{
int count= width*height;
for (int x= 0; x<width; ++x)
{
int count_adjustment= width - x - 1;
for (int y= 0, step= 1; y<height; ++y, step+= count_adjustment)
{
int last= count - (y+x*height);
int first= last - step;
std::rotate(matrix + first, matrix + first + 1, matrix + last);
}
}
}
transpose()
方法。 - MSNX_new = ((N*X) / (M*N)) + ((N*X) % (M*N))
M = 4
N = 3
MN = M*N
X = range(0,MN)
bitmap = (1<<0) + (1<<(MN-1))
i = 0
while bitmap != ( (1<<MN) - 1):
if (bitmap & (1<<i)):
i += 1
xin = X[i]
i = ((N*i)/MN) + ((N*i) % MN)
else:
xout = X[i]
X[i] = xin
bitmap += (1<<i)
i = ((N*i)/MN) + ((N*i) % MN)
xin = xout
print X