【问题标题】:Can I std::unique a std::priority_queue我可以 std::unique 一个 std::priority_queue
【发布时间】:2014-03-16 14:39:48
【问题描述】:

感谢您花时间阅读我的帖子。

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

是否有替代方案或可以做到?

友好的问候 GM3

@编辑

既然做不到,我会提供更多信息,以防有人能给我好的建议。

我想计算一组日期之间的天数,日期是出发日期或返回日期,我想计算在国外的天数和在国内的天数。可能有重复和重叠的行程。因此,我想从一个出发和一个单独的返回容器开始,并且没有重复的条目。我已经为日期对象重载了 = 运算符。

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

【问题讨论】:

  • 你不能。您必须将所有内容复制到另一个集合,对该集合执行所需的任何操作,然后将数据复制回队列中。
  • container adaptors 是容器周围的“带有属性的包装器”,它们不是真正的容器,它们为容器提供功能/不同的接口,请参见 stackoverflow.com/questions/4753690/… stackoverflow.com/questions/3873802/… ,@987654324 @ 和 queue 是标准中的另外 2 个容器适配器。
  • 这和unique_ptr有什么关系?
  • @user2485710,默认情况下priority_queue是一个向量,可以是std::unique'd,但仍然无法完成?
  • std::set 怎么样?

标签: c++ queue std


【解决方案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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-08-10
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 2012-04-25
    • 1970-01-01
    相关资源
    最近更新 更多