我有一个大小为n
的向量; n
是2的幂。我需要将此向量视为矩阵n
= R
* C
。然后我需要转置矩阵。
例如,我有矢量:[1,2,3,4,5,6,7,8]
我需要找到R和C.在这种情况下,它将是:4,2。并将矢量视为矩阵:
[1,2]
[3,4]
[5,6]
[7,8]
将其转置为:
[1, 3, 5, 7]
[2, 4, 6, 8]
换位后,载体应为:[1, 3, 5, 7, 2, 4, 6, 8]
是否存在执行就地非方矩阵转置的算法?我不想重新发明轮子。
我的矢量非常大,所以我不想创建中间矩阵。我需要一个就地算法。表现非常重要。
答案 0 :(得分:0)
由于您还未向我们提供任何代码,我是否可以建议采用不同的方法(我不知道哪种方法适用于您的特定情况)?
我会使用基于矩阵的算法自己将值转换为新矩阵。由于性能是一个问题,这将有助于更多,因为您不必创建另一个矩阵。如果这适用于您。
有一个载体
[1, 2, 3, 4, 5, 6, 7, 8]
创建矩阵
[1, 2]
[3, 4]
[5, 6]
[7, 8]
在没有其他矩阵的情况下重新排序矢量
[1, 3, 5, 7, 2, 4, 6, 8]
覆盖当前矩阵中的值(因此您不必创建新值)并根据当前矩阵重新排序值。
按顺序添加值
R1 and C1 to transposed_vector[0]
R2 and C1 to transposed_vector[1]
R3 and C1 to transposed_vector[2]
R4 and C1 to transposed_vector[3]
R1 and C2 to transposed_vector[4]
等等。
答案 1 :(得分:0)
问题可分为两部分。首先,找到R
和C
,然后重新整形矩阵。以下是我要做的事情:
由于n
是2
的强项,即n = 2^k
,如果k
是偶数,我们会:R=C=sqrt(n)
。如果k
为奇数,则为R = 2^((k+1)/2)
和C=2^((k-1)/2)
。
注意:由于您提到要避免使用额外的内存,我已经为原始答案制作了一些版本。
计算R
和C
的代码如下:
void getRandC(const size_t& n, size_t& R, size_t& C)
{
int k = (int)log2(double(n)),
i, j;
if (k & 1) // k is odd
i = (j = (k + 1) / 2) - 1;
else
i = j = k / 2;
R = (size_t)exp2(i);
C = (size_t)exp2(j);
}
哪个需要C ++ 11。对于第二部分,如果您想保留原始矢量:
void transposeVector(const std::vector<int>& vec, std::vector<int>& mat)
{
size_t R, C;
getRandC(vec.size(), R, C);
// first, reserve the memory
mat.resize(vec.size());
// now, do the transposition directly
for (size_t i = 0; i < R; i++)
{
for (size_t j = 0; j < C; j++)
{
mat[i * C + j] = vec[i + R * j];
}
}
}
而且,如果你想修改原始矢量并避免使用额外的内存,你可以写:
void transposeInPlace(std::vector<int>& vec)
{
size_t R, C;
getRandC(vec.size(), R, C);
for (size_t j = 0; R > 1; j += C, R--)
{
for (size_t i = j + R, k = j + 1; i < vec.size(); i += R)
{
vec.insert(vec.begin() + k++, vec[i]);
vec.erase(vec.begin() + i + 1);
}
}
}
答案 2 :(得分:0)
对于非方形矩阵表示,我认为它可能很棘手,并且不值得努力使平面向量转置而不创建另一个。这是我想出的一个片段:
chrono::steady_clock::time_point start = chrono::steady_clock::now();
int i, j, p, k;
vector<int> t_matrix(matrix.size());
for(k=0; k< R*C ;++k)
{
i = k/C;
j = k - i*C;
p = j*R + i;
t_matrix[p] = matrix[k];
}
cout << chrono::duration_cast<chrono::milliseconds> chrono::steady_clock::now() - start).count() << endl;
在这里,matrix
是您的平面向量,t_matrix
是&#34;转置&#34;平面向量,R
和C
分别是您为矩阵表示找到的行和向量。