提取向量的向量子集

Posted

技术标签:

【中文标题】提取向量的向量子集【英文标题】:Extract subset of vector of vectors 【发布时间】:2020-01-14 10:56:24 【问题描述】:

我知道如何从法线向量中提取子集,以及如何从另一个向量中的向量中提取子集。我现在的问题是如何提取另一个向量内的所有向量的子集。

例如:我在另一个向量中有三个向量:

std::vector<std::vector<int>> my_vec;
std::vector<int> vec_11,2,3,4,5;
std::vector<int> vec_211,12,13,14,15;
std::vector<int> vec_321,22,23,24,25;

my_vec.push_back(vec_1);
my_vec.push_back(vec_2);
my_vec.push_back(vec_3);

我现在要做的是创建一个新向量,其中包含每个向量的第三个和第四个元素的子集。 我试过这个:

#include<vector>
#include <iostream>

int main()

std::vector<std::vector<int>> my_vec;
std::vector<int> vec_11,2,3,4,5;
std::vector<int> vec_211,12,13,14,15;
std::vector<int> vec_321,22,23,24,25;

my_vec.push_back(vec_1);
my_vec.push_back(vec_2);
my_vec.push_back(vec_3);

// For a normal vector
std::vector<int> vec_1_subset(vec_1.begin()+2,vec_1.begin()+4);

for (auto& element: vec_1_subset)

std::cout<<element<<std::endl;


// For extracting from a single vector inside another vector
std::vector<int> my_vec_subset((my_vec[0]).begin()+2,(my_vec[0]).begin()+4);

for (auto& element: my_vec_subset)

std::cout<<element<<std::endl;


// For several vectors inside a vector ?
std::vector<std::vector<int>> my_vec_test_subset(my_vec.begin()+2,my_vec.begin()+4);

return 0;

最后一次尝试会产生错误消息。

【问题讨论】:

my_vec 是 int 向量的向量,my_vec_test_subset 是 int 向量。您正在尝试将 2 个向量复制到一个 int 向量中,这没有任何意义,因此会出现错误。 你是对的。我已经在代码中修复了它。这是创建示例代码时的错误。我仍然不明白如何提取每个向量的第三和第四个元素。 【参考方案1】:

你可能会这样做:

std::vector<std::vector<int>> res;
res.reserve(my_vec.size());

std::transform(my_vec.begin(), my_vec.end(),
               std::back_inserter(res),
               [](const std::vector<int>& v) return std::vector<int>v.begin() + 2,
                                                                      v.begin() + 4; );

【讨论】:

【参考方案2】:
auto GetVectorSubset(const vector<vector<int>>& source)

    std::vector<int> result;
    result.reserve(source.size()*2);

    for (const auto &vec: source)
    
        try
        
            result.emplace_back(vec.at(2));
            result.emplace_back(vec.at(3));
        
        catch(std::exception&) ;
    

    return result;

这个例子可能不是最理想的,但它很好并且可以完成工作。它依赖于这样一个事实,即 vector::at() 方法会在你越界时抛出异常。

如果异常对你来说太难看,你需要测试向量的大小 2 次:

if (vec.size() > 2) result.emplace_back(vec[2]);
if (vec.size() > 3) result.emplace_back(vec[3]);

【讨论】:

【参考方案3】:

跟进我的最新评论:

如果我正确理解了您的问题,那么下面给出了一种可能的方法:

#include <vector>
#include <iostream>

int main()
    std::vector<std::vector<int>> my_vec;
    std::vector<int> vec_11,2,3,4,5;
    std::vector<int> vec_211,12,13,14,15;
    std::vector<int> vec_321,22,23,24,25;
    my_vec.push_back(vec_1);
    my_vec.push_back(vec_2);
    my_vec.push_back(vec_3);
    std::vector<std::vector<int>> my_vec_test_subset;
    for(const auto vec:my_vec)
        my_vec_test_subset.push_back(vec.begin()+2,vec.begin()+4);
    for(const auto vec:my_vec_test_subset)
        for(const auto i:vec)
            std::cout<<i<<" ";
        std::cout<<std::endl;
    
    return 0;

输出

3 4 
13 14 
23 24

【讨论】:

您应该在循环中使用 /*const*/ auto& 以避免不必要的复制。此外,如果数组少于 4 个项目,您的代码将崩溃。 你是对的,谢谢!我正在避免长度检查,因为作者说他/她总是想检索第 3 和第 4 个元素。【参考方案4】:

my_vec_test_subset(my_vec.begin()+2,my_vec.begin()+4); 类型将是 std::vector> 不是 std::vector 而且 my_vec 只有三个(不是四个)元素,如果你修复类型会抛出异常

如果你想要一个包含元素 3 和 4 的 N 个向量的数组的 std::vector,下面的代码就是你需要的

    std::vector<int> finalV;
for (auto& element : my_vec) 
    finalV.insert(finalV.end(), element.begin()+2, element.begin()+4);

如果你想要一个包含 my_vec 元素的第 3 和第 4 个元素的向量向量,这是你需要的代码

std::vector<std::vector<int>> finalV2;
for (auto& element : my_vec) 
    finalV2.push_back(std::vector<int>(element.begin() + 2, element.begin() + 4));

【讨论】:

以上是关于提取向量的向量子集的主要内容,如果未能解决你的问题,请参考以下文章

R语言学习:提取R对象的子集

如何根据不同 R 生态系统中的另一个向量重写代码,将函数应用于行子集?

Rcpp中的布尔向量子集向量

量子支持向量机QSVM

Qisikit 量子隐形传输电路的状态向量

“子集”和“$ 运算符对原子向量无效”