我正在寻找一种优雅的方法来使用STL算法或增强来优先旋转矢量矢量 示例数据如下所示
vector<vector<int> > vm;
vector<int> v;
v.push_back(1);
v.push_back(2);
vm.push_back(v);
v.clear();
v.push_back(3);
v.push_back(4);
vm.push_back(v);
v.clear();
v.push_back(5);
v.push_back(6);
vm.push_back(v);
1 2
3 4
5 6
我想得到一个像这样的整数向量的向量
1 3 5
2 4 6
答案 0 :(得分:9)
我想最简单的解决方案就是编写一个简单的transpose
函数,其中包含两个循环:
std::vector<std::vector<int> > transpose(const std::vector<std::vector<int> > data) {
// this assumes that all inner vectors have the same size and
// allocates space for the complete result in advance
std::vector<std::vector<int> > result(data[0].size(),
std::vector<int>(data.size()));
for (std::vector<int>::size_type i = 0; i < data[0].size(); i++)
for (std::vector<int>::size_type j = 0; j < data.size(); j++) {
result[i][j] = data[j][i];
}
return result;
}
应该足够容易地优化返回值。我不认为通过使用任何标准功能会更简单或更有效,但我可能是错的。
另一种方法是将所有数据存储在一个单位vector
中,然后使用i, j
或类似内容计算元素i*row_length + j
的位置。这样,转置不涉及复制数据,只是改变索引的计算。
答案 1 :(得分:7)
看看Boost MultiArray。您可以创建sub-views数据。还有vnl_matrix,它有一个转置方法。
答案 2 :(得分:2)
我会介绍一个转换行的包装器 - &gt; col和col - &gt;行。这样可以防止您复制所有数据。
#include <iostream>
#include <vector>
template<typename T>
class TwoDPivotWrapper
{
public:
// These two typedef's were done with std::vector
// in mind. But with a small amount of effort I am
// sure they can be generalized. They are solely to define
// value_type (the data stored in the 2-D array).
typedef typename T::value_type OneDType;
typedef typename OneDType::value_type value_type;
// A constructor that wraps a 2-D structure.
TwoDPivotWrapper(T& o)
: object(o)
{}
// A helper class used to store the row after the first array accesses.
class Row
{
friend class TwoDPivotWrapper;
Row(TwoDWrapper& w, size_t r)
: wrapper(w)
, row(r)
{}
TwoDPivotWrapper& wrapper;
size_t row;
public:
value_type operator[](size_t col)
{
return wrapper.get(row,col);
}
};
// The operator [] returns a Row object that overloads
// the operator[] for the next dimension.
Row operator[](size_t row) {return Row(*this, row);}
// Generic get function used to access elements.
// Notice we swap the row/col around when accessing
// the underlying object.
value_type get(size_t row, size_t col) {return object[col][row];}
private:
T& object;
};
典型用法是:
int main()
{
typedef std::vector<std::vector<int> > TwoDVector;
TwoDVector data(3,std::vector<int>(2,0));
data[0][0] = 1; data[0][1] = 2;
data[1][0] = 3; data[1][1] = 4;
data[2][0] = 5; data[2][1] = 6;
TwoDPivotWrapper<TwoDVector> wrapper(data);
std::cout << wrapper[0][0] << wrapper[0][1] << wrapper[0][2] << "\n";
std::cout << wrapper[1][0] << wrapper[1][1] << wrapper[1][2] << "\n";
}
答案 3 :(得分:1)
如果你要在C ++中做很多线性代数,你应该看看Boost.uBlas。
#include <boost/numeric/ublas/matrix.hpp>
template <class M>
void printMatrix(const M& m)
{
for (size_t i=0; i<m.size1(); ++i)
{
for (size_t j=0; j<m.size2(); ++j)
std::cout << m(i,j) << " ";
std::cout << std::endl;
}
}
int main()
{
namespace ublas = boost::numeric::ublas;
typedef ublas::matrix<double> Matrix;
Matrix A(3, 2);
// Fill matrix A with incrementing values
double counter = 0.0;
for (size_t i=0; i<A.size1(); ++i)
for (size_t j=0; j<A.size2(); ++j)
A(i,j) = ++counter;
printMatrix(A);
std::cout << std::endl;
// Transpose A and store it in B
Matrix B = ublas::trans(A);
printMatrix(B);
return 0;
}
答案 4 :(得分:0)
它绝对必须是向量的载体吗?
如果没有,那么你可以在行*列元素的常规向量上实现一个包装器。
类似的东西:
class Vector
{
public:
int operator[]( int index )
{
return 1;
}
friend class Wrapper;
private:
Vector( std::vector<int> & vector, int index, int numElements );
std::vector<int> v_;
int index_;
int numElements_;
};
class Wrapper
{
public:
Vector operator[](int index)
{
return Vector( v_, index, numColumns_ );
}
Wrapper( int numRows, int numColumns);
void setNumRows( int numRows );
void setNumColumns( int numColumns );
private:
std::vector<int> v_;
int numRows_;
int numColumns_;
};
并在主要:
Wrapper w;
int i = w[1][1];
编辑:
Vector类将表示行或列数据。 作为参数,它需要线性化矩阵,矩阵几何(行数和列数)以及它代表的行/列。
用铅笔和纸试试: 1.以矩阵形式写出3x4矩阵的元素
11 12 13 14 21 22 23 24 31 32 33 34
11 12 13 14 21 22 23 24 31 32 33 34
矩阵形式的元素索引与线性化形式的索引之间存在简单的关系,这取决于矩阵的几何形状。
假设您的Vector需要引用矩阵中的第二列(即12 22 32)。 然后: - 向量中的第一项(即Vector [1])是线性化矩阵中的第二个元素 - 向量中的第二个项22是底层向量的第6个元素 - 向量中的第三个项目32是v _
的第10个元素现在,使用铅笔和纸张对矩阵的第三列(元素13 23 33)执行相同操作。 看看你是否发现第二列的基础向量中的索引(为2,6和10)与第三列的索引之间存在任何相似性。