根据一个向量内的值,从两个向量中删除项目。

5
我有两个相等长度的整数向量。假设我想删除第一个向量中所有的NAN项。显然,我使用remove_if算法。假设这将删除索引为1、2、5的元素。然后,我想从第二个向量中删除这些索引处的项目。
在C++中,最经典的方法是什么?

1
如果它们是相关的值,最常规的方法是将两个数据放在同一个对象中,并且有一个向量包含这些对象... - cdhowie
1
就像@cdhowie所说,如果您知道它们具有相同的长度并且值是相关联的,则应该首先使用std::vector<std::pair<int,int>> - PeterT
2个回答

11

可以使用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());

通过使用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));
                               });

实时演示


这太棒了。谢谢!我选择使用boost::combine生成一个范围,可以在remove_if中调用begin()和end(),我想应该没有什么实质性的区别吧? - experquisite
1
@experquisite 这是个非常好的主意,代码看起来整洁了许多。我已经把这个添加到答案里了。谢谢! - Praetorian

1
使用一个 vector<pair<int, int>> 将两个向量绑定在一起。然后,根据第一个元素执行删除操作,并同时将两个元素一起删除。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接