首页 > 解决方案 > Cpp 在多维向量中交换维度

问题描述

嘿,如果这个问题已经被问过,或者其他答案可以结合起来来接近我正在寻找的东西,我很抱歉。但是我对 Cpp 还很陌生,而且 STL 的东西可能会让人不知所措,所以请不要太挑剔,请把我链接到相应的答案。如果有人可以帮助我,我很高兴:

我有一个多维向量

std::vector<std::vector<std::vector<std::vector<definedTyp>>>> startingVec;

我想“交换”前两个维度,例如:假设startingVec有维度[dim, batches, batchSize, length],我想要swap前两个维度导致[batches, dim, batchSize, length]. 到目前为止,我定义了一个新向量并使用丑陋的 for 循环构建了一个解决方法,并只是附加了相应的向量,但我正在寻找一种优雅的方式,并且我愿意学习 STL(算法):) 希望我的问题变得清晰。提前致谢。

Edit: 我不知道这是否重要,但内部的尺寸batchSize不同,因为最后一批可能比前一批要小。

标签: c++

解决方案


正如评论中所说,您可以使用 1 个平面向量来存储所有数据,并使用特定的排序函数以您想要的顺序访问它。这是一个不相关(但更清晰)的数据结构的示例来说明:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <numeric>

struct Person {
    std::string name;
    size_t age;
    size_t height;
    float weight;
    
    static bool isYounger(const Person& p1, const Person& p2) { return p1.age < p2.age; }
    static bool isShorter(const Person& p1, const Person& p2) { return p1.height < p2.height; }
    static bool isLighter(const Person& p1, const Person& p2) { return p1.weight < p2.weight; }
};

template<typename Func_>
std::vector<size_t> generatesortedIdxBy(const std::vector<Person>& persons, Func_ sortingFunc) {
    std::vector<size_t> res ( persons.size() );
    std::iota(res.begin(), res.end(), 0);
    std::sort(res.begin(), res.end(), 
        [&](size_t id1, size_t id2){return sortingFunc(persons.at(id1), persons.at(id2));});
    return res;
}

int main()
{
    // Your "flat" data vector
    std::vector<Person> persons { 
        { "Alice", 60, 160, 45.f },
        { "Bob", 57, 180, 75.f }, 
        { "Charles", 30, 175, 108.f }, 
        { "David", 24, 165, 80.f }
    };
        
    // Your index vectors to access your data in different order
    std::vector<size_t> idxByAge = generatesortedIdxBy(persons, Person::isYounger); // { 3, 2, 0, 1 }
    std::vector<size_t> idxByHeight  = generatesortedIdxBy(persons, Person::isShorter); //{ 0, 3, 2, 1 }
    std::vector<size_t> idxByWeight = generatesortedIdxBy(persons, Person::isLighter); // { 0, 1, 3, 2 }
    
    
    std::cout << "By age: " << std::endl;
    for (auto idx: idxByAge) { 
        Person& person = persons.at(idx);
        std::cout << person.name << std::endl;
    }
    std::cout << std::endl;
    
    std::cout << "By height: " << std::endl;
    for (auto idx: idxByHeight) { 
        Person& person = persons.at(idx);
        std::cout << person.name << std::endl;
    }
    std::cout << std::endl;
    
    std::cout << "By weight: " << std::endl;
    for (auto idx: idxByWeight) { 
        Person& person = persons.at(idx);
        std::cout << person.name << std::endl;
    }
    std::cout << std::endl;
        
}

推荐阅读