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

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

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

std::vector<std::vector<int>> my_vec;
std::vector<int> vec_1{1,2,3,4,5};
std::vector<int> vec_2{11,12,13,14,15};
std::vector<int> vec_3{21,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_1{1,2,3,4,5};
std::vector<int> vec_2{11,12,13,14,15};
std::vector<int> vec_3{21,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 向量中,这没有任何意义,因此会出现错误。
  • 你是对的。我已经在代码中修复了它。这是创建示例代码时的错误。我仍然不明白如何提取每个向量的第三和第四个元素。

标签: c++ vector subset


【解决方案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_1{1,2,3,4,5};
          std::vector<int> vec_2{11,12,13,14,15};
          std::vector<int> vec_3{21,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));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-25
        相关资源
        最近更新 更多