STL:set_union,includes,mismatch,find_if但是没有includes_any?

时间:2010-08-31 20:35:30

标签: c++ stl

从标题中,您几乎可以肯定会使用set_union来创建list,然后检查它是否为空。但是,我正在比较的对象要复制“昂贵”。我查看了includes,但只有在 all 一个列表的项目在另一个列表中找到时才有效。我也看了mismatch,但出于显而易见的原因拒绝了它。

我可以编写自己的函数,假设两个列表都已排序,但我想知道STL中是否已存在高效函数。 (项目被禁止使用第三方库,包括Boost和TR1,请不要问。)

2 个答案:

答案 0 :(得分:3)

如果集未排序,则可以使用find_first_of作为O(N * M)算法。

如果它们被排序(无论如何都需要set_intersection),那么你可以迭代一个集合,在另一个集合中为每个元素调用equal_range。如果每个返回的范围都是空的,则没有交集。性能为O(N log M)。

然而,没有理由没有O(N + M)表现,对吧?如果set_intersection传递了虚拟迭代器,则不会复制任何内容。

struct found {};

template< class T > // satisfy language requirement
struct throwing_iterator : std::iterator< std::output_iterator_tag, T > {
    T &operator*() { throw found(); }
    throwing_iterator &operator++() { return *this; }
    throwing_iterator operator++(int) { return *this; }
};

template< class I, class J >
bool any_intersection( I first1, I last1, J first2, J last2 ) {
    try {
        throwing_iterator< typename std::iterator_traits<I>::value_type > ti;
        set_intersection( first1, last1, first2, last2, ti );
        return false;
    } catch ( found const& ) {
        return true;
    }
}

这提供了提前退出。您可以选择性地避免异常,只需让迭代器记住它增加了多少次,并且无操作分配。

答案 1 :(得分:1)

find_first_of()你追求的是什么?