C++中如何从现有3D vector的列构造新3D vector
3D Vector 转置构造实现
需求:现有如下结构的3D vector,需要通过遍历索引,将原vector的列(j索引)重新组织成指定结构的新3D vector。
输入结构
std::vector<std::vector<std::vector<double>>> a = { { {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}, {5,5,5,5}, {6,6,6,6} }, { {10,10,10,10}, {20,20,20,20}, {30,30,30,30}, {40,40,40,40}, {50,50,50,50}, {60,60,60,60} }, { {100,100,100,100}, {200,200,200,200}, {300,300,300,300}, {400,400,400,400}, {500,500,500,500}, {600,600,600,600} }, };
目标输出结构
std::vector<std::vector<std::vector<double>>> b = { {{ 1,1,1,1}, {10,10,10,10}, {100,100,100,100}}, {{ 2,2,2,2}, {20,20,20,20}, {200,200,200,200}}, {{ 3,3,3,3}, {30,30,30,30}, {300,300,300,300}}, {{ 4,4,4,4}, {40,40,40,40}, {400,400,400,400}}, {{ 5,5,5,5}, {50,50,50,50}, {500,500,500,500}}, {{ 6,6,6,6}, {60,60,60,60}, {600,600,600,600}}, };
现有代码框架
#include <iostream> #include <vector> using namespace std; void show3D_vector(std::vector<std::vector<std::vector<double>>>& a); void show2D_vector(std::vector<std::vector<double>>& a); template<typename T> std::vector<std::vector<T>> SplitVector(const std::vector<T>& vec, size_t n); int main() { std::vector<std::vector<std::vector<double>>> a = { { {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}, {5,5,5,5}, {6,6,6,6} }, { {10,10,10,10}, {20,20,20,20}, {30,30,30,30}, {40,40,40,40}, {50,50,50,50}, {60,60,60,60} }, { {100,100,100,100}, {200,200,200,200}, {300,300,300,300}, {400,400,400,400}, {500,500,500,500}, {600,600,600,600} }, }; } void show3D_vector(std::vector<std::vector<std::vector<double>>>& a) { for (double i = 0; i < a.size(); ++i) { for (double j = 0; j < a[i].size(); ++j) { for (double k = 0; k < a[i][j].size(); ++k) std::cout << a[i][j][k] << " "; std::cout << endl; } std::cout << endl; } } void show2D_vector(std::vector<std::vector<double>>& a) { for (int i = 0; i < a.size(); i++) { for (auto it = a[i].begin(); it != a[i].end(); it++) { std::cout << *it << " "; } std::cout << endl << endl; } } template<typename T> std::vector<std::vector<T>> SplitVector(const std::vector<T>& vec, size_t n) { std::vector<std::vector<T>> outVec; size_t length = vec.size() / n; size_t remain = vec.size() % n; size_t begin = 0; size_t end = 0; for (size_t i = 0; i < std::min(n, vec.size()); ++i) { end += (remain > 0)? (length + !!(remain--)) : length; outVec.push_back(std::vector<T>(vec.begin() + begin, vec.begin() + end)); begin = end; } return outVec; }
解决方案
核心思路
输入的3D vector维度为 [3][6][4],目标输出维度为 [6][3][4],本质是将原数组的第一维和第二维进行转置:原数组的 a[i][j] 对应目标数组的 b[j][i]。
修改后的完整代码
#include <iostream> #include <vector> using namespace std; void show3D_vector(std::vector<std::vector<std::vector<double>>>& a); void show2D_vector(std::vector<std::vector<double>>& a); template<typename T> std::vector<std::vector<T>> SplitVector(const std::vector<T>& vec, size_t n); int main() { std::vector<std::vector<std::vector<double>>> a = { { {1,1,1,1}, {2,2,2,2}, {3,3,3,3}, {4,4,4,4}, {5,5,5,5}, {6,6,6,6} }, { {10,10,10,10}, {20,20,20,20}, {30,30,30,30}, {40,40,40,40}, {50,50,50,50}, {60,60,60,60} }, { {100,100,100,100}, {200,200,200,200}, {300,300,300,300}, {400,400,400,400}, {500,500,500,500}, {600,600,600,600} }, }; // 构造目标3D vector std::vector<std::vector<std::vector<double>>> b; // 原数组第二维的大小就是目标数组第一维的大小 size_t target_first_dim = a[0].size(); // 原数组第一维的大小就是目标数组第二维的大小 size_t target_second_dim = a.size(); // 初始化b的结构 b.resize(target_first_dim); for (size_t j = 0; j < target_first_dim; ++j) { b[j].resize(target_second_dim); } // 遍历索引赋值 for (size_t i = 0; i < target_second_dim; ++i) { for (size_t j = 0; j < target_first_dim; ++j) { b[j][i] = a[i][j]; } } // 打印原数组和目标数组验证 cout << "原数组:" << endl; show3D_vector(a); cout << "目标数组:" << endl; show3D_vector(b); } void show3D_vector(std::vector<std::vector<std::vector<double>>>& a) { // 修正循环变量类型:用size_t而非double,避免精度问题 for (size_t i = 0; i < a.size(); ++i) { for (size_t j = 0; j < a[i].size(); ++j) { for (size_t k = 0; k < a[i][j].size(); ++k) std::cout << a[i][j][k] << " "; std::cout << endl; } std::cout << endl; } } void show2D_vector(std::vector<std::vector<double>>& a) { for (int i = 0; i < a.size(); i++) { for (auto it = a[i].begin(); it != a[i].end(); it++) { std::cout << *it << " "; } std::cout << endl << endl; } } template<typename T> std::vector<std::vector<T>> SplitVector(const std::vector<T>& vec, size_t n) { std::vector<std::vector<T>> outVec; size_t length = vec.size() / n; size_t remain = vec.size() % n; size_t begin = 0; size_t end = 0; for (size_t i = 0; i < std::min(n, vec.size()); ++i) { end += (remain > 0)? (length + !!(remain--)) : length; outVec.push_back(std::vector<T>(vec.begin() + begin, vec.begin() + end)); begin = end; } return outVec; }
关键说明
- 维度转换:通过获取原数组的第一维和第二维大小,初始化目标数组的结构,保证维度匹配。
- 索引遍历:嵌套循环遍历原数组的
i(第一维)和j(第二维),将a[i][j]直接赋值给b[j][i],完成列到行的转换。 - 修正打印函数:原
show3D_vector中使用double作为循环索引存在精度风险,改为size_t更安全(符合容器大小的类型)。
内容的提问来源于stack exchange,提问作者Prostoy_paren
相关产品推荐
相关产品推荐

