【问题标题】:Iterate over objects which are contained in the intersection of two ranges迭代包含在两个范围的交集中的对象
【发布时间】:2017-03-26 14:42:19
【问题描述】:

标准库中有什么东西可以让我遍历包含在两个范围交集中的对象吗?

特别是给定一个函数对象action,我想得到一个等价于的程序

/* some container supporting a push_back operation */ intersection;
std::set_intersection(first1, last1, first2, last2,
    std::back_inserter(intersection));
for (auto const& element : intersection)
    action(element);

无需插入intersection。当然,写这样的代码很容易,例如

template<class InputIt1, class InputIt2, class UnaryFunction>
void for_each_in_intersection(InputIt1 first1, InputIt1 last1,
    InputIt2 first2, InputIt2 last2, UnaryFunction f)
{
    while (first1 != last1 && first2 != last2)
    {
        if (*first1 < *first2)
            ++first1;
        else
        {
            if (!(*first2 < *first1))
                f(*first1++);
            ++first2;
        }
    }
}

但我希望标准库中已经有一些可用的东西。

【问题讨论】:

标签: c++ stl containers c++14 c++-standard-library


【解决方案1】:

你可以使用 boost 中的Function Output Iterator

#include <boost/function_output_iterator.hpp>
#include <vector>
#include <iostream>
#include <algorithm>

int main() {
    std::vector<int> v1 = {1, 2, 3, 4, 5};
    std::vector<int> v2 = {2, 4};
    std::set_intersection(v1.begin(), v1.end(), v2.begin(), v2.end(),
            boost::make_function_output_iterator([](int i) {
                std::cout << i * i << '\n';
            }));
}

【讨论】:

  • 很酷的东西!我建议使用this link,它总是指向最新的 boost 版本。
【解决方案2】:

我不知道 STL 中的任何内容都可以以比您编写的代码更好的方式做您想做的事情。

我能想到的更简单的方法是 std::for_each()std::find() std::binary_search()(感谢 Rakete1111)和一个 lambda 函数。但我认为这不是一个好主意,因为不使用 容器是有序的这一事实搜索的值是有序的。

以下是一个完整的工作示例

#include <vector>
#include <iostream>
#include <algorithm>

template <typename T>
void action (T const & val)
 { std::cout << "- action over " << val << std::endl; }

int main()
 {
   std::vector<int> v1 { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };
   std::vector<int> v2 { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };

   std::for_each(v1.cbegin(), v1.cend(),
                 [&](int val) {
      if ( std::binary_search(v2.cbegin(), v2.cend(), val) )
         action(val);
    });
 }

【讨论】:

  • 您可以使用std::binary_search 代替std::find,因为容器已排序,因此速度更快。
  • @Rakete1111 - 我没有考虑过std::binary_search();谢谢;所以真的更好
猜你喜欢
  • 2016-01-26
  • 2018-06-14
  • 2014-11-22
  • 2014-07-04
  • 2018-10-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-28
相关资源
最近更新 更多