【问题标题】:Remove items from two vectors depending on the values inside one vector根据一个向量内的值从两个向量中删除项目
【发布时间】:2014-10-30 16:20:47
【问题描述】:

我有两个等长的整数向量。假设我想删除第一个向量中所有 NAN 项。显然,我使用了 remove_if 算法。假设这会删除索引为 1、2、5 的元素。然后我想从这些索引处的第二个向量中删除项目。

最规范的 C++ 方法是什么?

【问题讨论】:

  • 如果它们是相关值,最规范的方法是将两条数据放在同一个对象中,并有一个包含这些对象的向量...
  • 就像@cdhowie 说的那样,如果你知道它们的长度相同并且值是链接的,那么你首先应该有一个std::vector<std::pair<int,int>>

标签: c++ vector stl


【解决方案1】:

这可以通过使用 Boost 创建 zip_iterator 然后从两个容器并行迭代迭代器的 tuple 来完成。

首先将一对zip_iterators 传递给std::remove_if,并让谓词检查第一个vector 的元素是否为NaN

auto result = std::remove_if(boost::make_zip_iterator(boost::make_tuple(v1.begin(), v2.begin())),
                             boost::make_zip_iterator(boost::make_tuple(v1.end(),   v2.end())),
                             [](boost::tuple<double, int> const& elem) {
                                 return std::isnan(boost::get<0>(elem));
                             });

然后使用vector::erase 删除不需要的元素。

v1.erase(boost::get<0>(result.get_iterator_tuple()), v1.end());
v2.erase(boost::get<1>(result.get_iterator_tuple()), v2.end());

Live demo


使用boost::combine 和Boost.Range 的remove_if 版本可以进一步减少创建压缩迭代器范围所需的样板文件。

auto result = boost::remove_if(boost::combine(v1, v2),
                               [](boost::tuple<double, int> const& elem) {
                                    return std::isnan(boost::get<0>(elem));
                               });

Live demo

【讨论】:

  • 这太棒了。谢谢!我选择使用 boost::combine 来生成一个可以在 remove_if 中调用 begin() 和 end() 的范围,我认为没有真正的区别?
  • @experquisite 这是一个绝妙的主意,对代码进行了相当多的清理。我将其添加到答案中。谢谢!
【解决方案2】:

使用vector&lt;pair&lt;int, int&gt;&gt; 将两个向量绑定在一起。然后,根据第一个元素执行删除并同时删除两者。

【讨论】:

    猜你喜欢
    • 2020-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多