我可以std :: unique一个std :: priority_queue

时间:2014-03-16 14:39:48

标签: c++ queue std

感谢您抽出宝贵时间阅读我的帖子。

我需要一个唯一的优先级队列,但是没有选项来获取它的迭代器:(

有替代方案还是可以做到?

友好的问候 GM3

@edit

由于无法完成,我会提供更多信息,以防有人给我很好的建议。

我想计算一组日期,日期是离开或返回日期之间的日子,我想要计算国外的日子和家里的日子。可能存在重复和重叠的旅行。因此,我想从一个离开和一个单独的返回容器开始订购,没有重复的条目。我已经超载了< > =日期对象的运算符。

由于运行时内存分配,我之前没有使用过stl容器,但是在这种情况下我没有这样的限制,并且想要习惯使用它们。我最初想使用priority_queue,但现在我怀疑我的选择。

1 个答案:

答案 0 :(得分:1)

  • 即使可以像std::priority_queue一样指定std::stack的序列容器,也必须指定一个能够维护插入顺序的非关联容器,例如std::vectorstd::deque(使用随机访问迭代器)。 即使此处可以使用std::set来删除重复项,std::priority_queue也不会返回指示是否已插入元素,如std::setstd::map
  • 带有自定义比较器的普通std::set效果很好,可以使用begin()rbegin() erase()插入和删除元素。
  • 另一种方法是在序列容器中手动维护自定义堆。通常这样做是为了避免因关联容器或链接列表(如std::setstd::mapstd::liststd::forward_list,...)的链接结构导致的内存碎片和某些性能损失。 :
  • 另请注意,std::heap*算法允许维护特定于实现的顺序,因此不能期望产生与std::sort()相同的结果。
#include <iostream>
#include <numeric>
#include <algorithm>
#include <vector>
#include <deque>
#include <cstdlib>

///@brief Internal insert function for ordered sequences
template<class SequenceContainer, typename Value, class Comparator>
inline typename std::pair<typename SequenceContainer::iterator, bool> heap_set_insert_(SequenceContainer& heap, const Value& value, Comparator comparator)
{
    std::pair<typename SequenceContainer::iterator, bool> result(std::lower_bound(heap.begin(), heap.end(), value, comparator), false);
    if (!(result.first != heap.end() && !comparator(value, *result.first)))
    {
        result.first = heap.insert(result.first, value);
        result.second = true;
    }
    return result;
}

/**
 * @brief insert function for an ordered vector, works like std::set::insert(const value_type&)
 * @param heap The supplied container must already be sorted using the specified comparator
 */
template<typename T, class Allocator, class Comparator = std::less<T> >
inline typename std::pair<typename std::vector<T, Allocator>::iterator, bool> heap_set_insert(std::vector<T, Allocator>& heap, const T& value, Comparator comparator)
{
    return heap_set_insert_<std::vector<T> >(heap, value, comparator);
}

/**
 * @brief insert function for an ordered deque, works like std::set::insert(const value_type&)
 * @param heap The supplied container must already be sorted using the specified comparator
 */
template<typename T, class Allocator, class Comparator = std::less<T> >
inline typename std::pair<typename std::deque<T, Allocator>::iterator, bool> heap_set_insert(std::deque<T, Allocator>& heap, const T& value, Comparator comparator)
{
    return heap_set_insert_<std::deque<T> >(heap, value, comparator);
}

///@brief Prints all elements of any container as an array to a std::ostream: {[,elem]...}.
///@note Special container elements and std::pair<> may need additional ostream overloads
template<class Container>
inline std::ostream& print_container_(std::ostream& o, const Container& s)
{
    o << '{';
    for (typename Container::const_iterator it = s.begin(); it != s.end(); ++it)
    {
        if (it != s.begin())
            o << ',';
        o << *it;
    }
    o << '}';
    return o;
}

///@brief Equality functor, derived from a set comparator (which may evaluate less/greater than).
template<typename SetComparator>
class SetAdjacencyComparator
{
public:
    SetAdjacencyComparator(const SetComparator& setCmp = SetComparator()) :
            setCmp(setCmp)
    {
    }

    //Elements are equal, if neither is less/greater than the other
    bool operator()(int a, int b)
    {
        return !setCmp(a, b) && !setCmp(b, a);
    }
private:
    SetComparator setCmp;
};

int main()
{
    //May be a function pointer
    //For a set (with unique values), use less/greater only!
    typedef std::less<int> MyCompare;
    MyCompare cmp;

    std::cout << std::boolalpha;

    {
        std::deque<int> s
        { 7, 8, 3, 4, 9, 10, 1, 2, 6, 5 };  //(C++11)

        //Initialize the custom heap using the one comparator, which is used for all subsequent operations
        std::sort(s.begin(), s.end(), cmp);

        print_container_(std::cout, s) << std::endl;

        std::cout << "inserted: " << heap_set_insert(s, 3, cmp).second << std::endl;
        std::cout << "inserted: " << heap_set_insert(s, 33, cmp).second << std::endl;
        std::cout << "inserted: " << heap_set_insert(s, 11, cmp).second << std::endl;

        print_container_(std::cout, s) << std::endl;

        std::cout << "is_sorted() : " << std::is_sorted(s.begin(), s.end(), cmp) << std::endl;
        std::cout << "unique      : " << (std::adjacent_find(s.begin(), s.end(), SetAdjacencyComparator<MyCompare>(cmp)) == s.end()) << std::endl;
        //^- In order for this check to work, the sequence must be sorted in such a way, that equal elements are adjacent

        std::cout << "highest (top) : " << s.back() << std::endl;
        std::cout << "lowest        : " << s.front() << std::endl;
    }

    std::cout << std::noboolalpha;

    return EXIT_SUCCESS;
}