【问题标题】:Constructing a priority queue of vectors构造向量的优先级队列
【发布时间】:2018-02-17 11:09:19
【问题描述】:

我正在寻找向量优先级队列的简单 STL 实现。每个向量正好有 4 个元素。我想根据每个向量的第三个元素对我的优先级队列进行排序。第三个元素最低的向量应该在顶部(向量的最小优先级队列)。

如何在 C++ 中实现?

另外,如果有人有默认优先级队列的实际 STL 实现,请提供链接。就像 STL 内部的官方实现一样。

【问题讨论】:

  • 使用std::array,对于固定尺寸我会更有效率。
  • @RHertel 使用标准数组容器并为std::priority_queue提供自定义比较器不是更好吗?
  • @DanielLangr 是的,我知道,但我的代码的其他实现需要矢量属性。不过还是谢谢你。
  • @RHertel 您有阅读此内容的链接吗?任何材料都会有所帮助。

标签: c++ c++11 stl


【解决方案1】:

您必须创建自己的比较器来比较priority_queue 的元素。

类似这样的:

// How to compare elements
struct my_comparator
{
    // queue elements are vectors so we need to compare those
    bool operator()(std::vector<int> const& a, std::vector<int> const& b) const
    {
        // sanity checks
        assert(a.size() == 4);
        assert(b.size() == 4);

        // reverse sort puts the lowest value at the top    
        return a[2] > b[2];
    }
};

// for usability wrap this up in a type alias:
using my_priority_queue = std::priority_queue<std::vector<int>, std::vector<std::vector<int>>, my_comparator>;

int main()
{
    my_priority_queue mpq;

    mpq.push({1, 2, 1, 4});
    mpq.push({1, 2, 2, 4});
    mpq.push({1, 2, 3, 4});

    // etc ...
}

【讨论】:

    【解决方案2】:

    请考虑使用 STL 数据结构 priority_queue。我以前遇到过类似的问题,这段代码应该会有所帮助。

    我认为在发布答案之前,我们需要检查我们的答案是否正确。所以这是工作程序,但你不应该使用using namespace std;,请用std::更改它:

    #include <functional>
    #include <queue>
    #include <vector>
    #include <iostream>
    
    using namespace std;
    
    template<typename T> void print_queue(T& q) {
        while(!q.empty()) {
            vector<int> tmp;
            tmp = q.top();
            std::cout << tmp[2] << " ";
            q.pop();
        }
        std::cout << '\n';
    }
    
    struct Compare {
        bool operator()(vector<int> const & a, vector<int> const & b)
        { return a[2] > b[2]; }
    };
    
    int main()
    {
    
        vector<int> v1;
        vector<int> v2;
        vector<int> v3;
        vector<int> v4;
    
        priority_queue< vector<int>, vector< vector<int> >, Compare > pr_q;
    
        int a[5] = { 1,2,3,4 };
        v1.insert(v1.end(), a, a+4); v1[2] = 11; // v1 = {1, 2, 11, 4}
        v2.insert(v2.end(), a, a+4); v2[2] = -1; // v1 = {1, 2, -1, 4}
        v3.insert(v3.end(), a, a+4); v3[2] = 22; // v1 = {1, 2, 22, 4}
        v4.insert(v4.end(), a, a+4); v4[2] = 31; // v1 = {1, 2, 31, 4}
    
        pr_q.push(v1);
        pr_q.push(v2);
        pr_q.push(v3);
        pr_q.push(v4);
    
        print_queue(pr_q);
    
        return 0;
    }
    

    【讨论】:

    • 我知道可以应用一些改进和更正,但我认为它回答了这个问题。所以,干杯!
    • 比较器符号应该是“大于”,因为默认情况下优先级队列是使用最大堆而不是最小堆实现的。我认为您应该更改比较符号。
    【解决方案3】:

    您可以将std::priority_queue 与自定义比较器一起使用。

    using QueueElement = std::vector<int>;
    
    auto compare_third_element = [](const QueueElement& lhs, const QueueElement& rhs) 
                                 { 
                                    assert(lhs.size() > 2 && rhs.size() > 2);
                                    return lhs[2] > rhs[2]; 
                                 };
    
    using MyPriorityQueue = std::priority_queue < QueueElement, std::vector<QueueElement>, decltype(compare_third_element)>;
    MyPriorityQueue my_queue(compare_third_element);
    
    my_queue.emplace(QueueElement{ 0,0,2 });
    my_queue.emplace(QueueElement{ 0,0,3 });
    my_queue.emplace(QueueElement{ 0,0,1 });
    

    【讨论】:

      【解决方案4】:

      Galiks 的例子很好。但是,如果遵循一项功能 - 一项任务的原则,我不会将健全性检查放在比较器中。有关http://en.cppreference.com/w/cpp/container/priority_queue 的更多详细信息。使用 lambda 我们可以如下实现:

      #include <vector>
      #include <queue>
      
      int main(){
          auto cmp = [](std::vector<int> left, std::vector<int> right) { return(left[2]) > (right[2]);};
      
          std::priority_queue<std::vector<std::vector<int>>, std::vector<std::vector<int>>, decltype(cmp)> q(cmp);
      
          q.push({1,2,1,3});
          q.push({1,2,2,3});
          q.push({1,2,3,3});
          q.push({1,2,4,3});
      
          return 0;
      }
      

      【讨论】:

        【解决方案5】:
        #include<iostream>
        #include<queue>
        
        using namespace std; 
        
        priority_queue<vector<int>> pq; 
        
        void max(vector<int> v) 
        { 
            for(int i=0; i<v.size();i++) 
            { 
                cout<<v[i]<<" "; 
            } 
            cout<<endl; 
            return; 
        } 
        
        int main() 
        { 
            vector<int> inp1{10,20,30,40}; 
            vector<int> inp2{10,20,35,40}; 
            vector<int> inp3{30,25,10,50};
            vector<int> inp4{20,10,30,40};
            vector<int> inp5{5,10,30,40};
        
            pq.push(inp1); 
            pq.push(inp2); 
            pq.push(inp3); 
            pq.push(inp4); 
            pq.push(inp5); 
            max(pq.top()); 
        } 
        

        【讨论】:

        • 打印队列中的最大向量 像这样定义优先级队列 priority_queue > "Queuename";
        【解决方案6】:

        #包括 #包括

        使用命名空间标准;

        void max(vector<int> v) 
        { 
        for(int i=0; i<v.size();i++) 
        { 
            cout<<v[i]<<" "; 
        } 
        cout<<endl; 
        };
        
        struct my_comparator
        {
            bool operator()(vector<int> const& a,vector<int> const& b) const
            {
                return a>b;
            }
        };
        
        priority_queue<vector<int>, vector<vector<int>>, my_comparator>pq;
        
        int main() 
        {
            vector<int> inp1{10,20,30,40}; 
            vector<int> inp2{10,20,35,40}; 
            vector<int> inp3{30,25,10,50};
            vector<int> inp4{20,10,30,40};
            vector<int> inp5{5,10,30,40};
        
            pq.push(inp1); 
            pq.push(inp2); 
            pq.push(inp3); 
            pq.push(inp4); 
            pq.push(inp5); 
        
            max(pq.top()); 
        } 
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-12-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-20
          相关资源
          最近更新 更多