簡體   English   中英

如何對對象使用優先隊列 STL?

[英]How to use the priority queue STL for objects?

class Person
{
public:
    int age;
};

我想將 Person 類的對象存儲在優先級隊列中。

priority_queue< Person, vector<Person>, ??? >

我想我需要為比較事物定義一個類,但我不確定。

此外,當我們寫作時,

priority_queue< int, vector<int>, greater<int> > 

更大的工作如何?

您需要為存儲在隊列中的類型(在本例中為Person提供有效的嚴格弱排序比較。 默認是使用std::less<T> ,它解析為與operator<等效的東西。 這依賴於它自己的存儲類型。 所以如果你要實施

bool operator<(const Person& lhs, const Person& rhs); 

它應該無需任何進一步更改即可工作。 實施可能是

bool operator<(const Person& lhs, const Person& rhs)
{
  return lhs.age < rhs.age;
}

如果該類型沒有自然的“小於”比較,則提供您自己的謂詞而不是默認的std::less<Person>會更有意義。 例如,

struct LessThanByAge
{
  bool operator()(const Person& lhs, const Person& rhs) const
  {
    return lhs.age < rhs.age;
  }
};

然后像這樣實例化隊列:

std::priority_queue<Person, std::vector<Person>, LessThanByAge> pq;

關於使用std::greater<Person>作為比較器,這將使用等效的operator>並具有創建優先級反轉 WRT 默認情況下的隊列的效果。 這將需要一個operator>的存在,該operator>可以對兩個Person實例進行操作。

您將編寫一個比較器類,例如:

struct CompareAge {
    bool operator()(Person const & p1, Person const & p2) {
        // return "true" if "p1" is ordered before "p2", for example:
        return p1.age < p2.age;
    }
};

並將其用作比較器參數:

priority_queue<Person, vector<Person>, CompareAge>

使用greater會給出與默認值相反的順序less ,這意味着隊列將為您提供最低值而不是最高值。

優先級隊列是一種抽象數據類型,它捕捉容器的概念,其元素具有附加到它們的“優先級”。 最高優先級的元素總是出現在隊列的前面。 如果該元素被移除,則下一個優先級最高的元素會前進到最前面。

C++標准庫定義了一個類模板priority_queue,操作如下:

push :將一個元素插入優先隊列。

top :從優先級隊列中返回(不刪除)最高優先級的元素。

pop :從優先級隊列中刪除最高優先級的元素。

size :返回優先級隊列中元素的數量。

empty : 根據優先級隊列是否為空,返回真或假。

以下代碼片段顯示了如何構造兩個優先級隊列,一個可以包含整數,另一個可以包含字符串:

#include <queue>

priority_queue<int> q1;
priority_queue<string> q2;

以下是優先級隊列使用的示例:

#include <string>
#include <queue>
#include <iostream>

using namespace std;  // This is to make available the names of things defined in the standard library.

int main()
{
    piority_queue<string> pq; // Creates a priority queue pq to store strings, and initializes the queue to be empty.

    pq.push("the quick");
    pq.push("fox");
    pq.push("jumped over");
    pq.push("the lazy dog");

    // The strings are ordered inside the priority queue in lexicographic (dictionary) order:
    // "fox", "jumped over", "the lazy dog", "the quick"
    //  The lowest priority string is "fox", and the highest priority string is "the quick"

    while (!pq.empty()) {
       cout << pq.top() << endl;  // Print highest priority string
       pq.pop();                    // Remmove highest priority string
    }

    return 0;
}

這個程序的輸出是:

the quick
the lazy dog
jumped over
fox

由於隊列遵循優先級規則,因此字符串從最高優先級到最低優先級打印。

有時需要創建一個優先級隊列來包含用戶定義的對象。 在這種情況下,優先級隊列需要知道用於確定哪些對象具有最高優先級的比較標准。 這是通過屬於重載運算符 () 的類的函數對象來完成的。 重載的 () 充當 < 用於確定優先級。 例如,假設我們要創建一個優先級隊列來存儲 Time 對象。 Time 對象具有三個字段:小時、分鍾、秒:

struct Time {
    int h; 
    int m; 
    int s;
};

class CompareTime {
    public:
    bool operator()(Time& t1, Time& t2) // Returns true if t1 is earlier than t2
    {
       if (t1.h < t2.h) return true;
       if (t1.h == t2.h && t1.m < t2.m) return true;
       if (t1.h == t2.h && t1.m == t2.m && t1.s < t2.s) return true;
       return false;
    }
}

根據上述比較標准存儲時間的優先隊列將定義如下:

priority_queue<Time, vector<Time>, CompareTime> pq;

Here is a complete program:

#include <iostream>
#include <queue>
#include <iomanip>

using namespace std;

struct Time {
    int h; // >= 0
    int m; // 0-59
    int s; // 0-59
};

class CompareTime {
public:
    bool operator()(Time& t1, Time& t2)
    {
       if (t1.h < t2.h) return true;
       if (t1.h == t2.h && t1.m < t2.m) return true;
       if (t1.h == t2.h && t1.m == t2.m && t1.s < t2.s) return true;
       return false;
    }
};

int main()
{
    priority_queue<Time, vector<Time>, CompareTime> pq;

    // Array of 4 time objects:

    Time t[4] = { {3, 2, 40}, {3, 2, 26}, {5, 16, 13}, {5, 14, 20}};

    for (int i = 0; i < 4; ++i)
       pq.push(t[i]);

    while (! pq.empty()) {
       Time t2 = pq.top();
       cout << setw(3) << t2.h << " " << setw(3) << t2.m << " " <<
       setw(3) << t2.s << endl;
       pq.pop();
    }

    return 0;
}

該程序從最晚到最早打印時間:

5  16  13
5  14  20
3   2  40
3   2  26

如果我們希望最早的時間具有最高優先級,我們可以像這樣重新定義 CompareTime:

class CompareTime {
public:
    bool operator()(Time& t1, Time& t2) // t2 has highest prio than t1 if t2 is earlier than t1
    {
       if (t2.h < t1.h) return true;
       if (t2.h == t1.h && t2.m < t1.m) return true;
       if (t2.h == t1.h && t2.m == t1.m && t2.s < t1.s) return true;
       return false;
    }
};

這段代碼可能會有所幫助..

#include <bits/stdc++.h>
using namespace std;    

class node{
public:
    int age;
    string name;
    node(int a, string b){
        age = a;
        name = b;
    }
};

bool operator<(const node& a, const node& b) {

    node temp1=a,temp2=b;
    if(a.age != b.age)
        return a.age > b.age;
    else{
        return temp1.name.append(temp2.name) > temp2.name.append(temp1.name);
    }
}

int main(){
    priority_queue<node> pq;
    node b(23,"prashantandsoon..");
    node a(22,"prashant");
    node c(22,"prashantonly");
    pq.push(b);
    pq.push(a);
    pq.push(c);

    int size = pq.size();
    for (int i = 0; i < size; ++i)
    {
        cout<<pq.top().age<<" "<<pq.top().name<<"\n";
        pq.pop();
    }
}

輸出:

22 prashantonly
22 prashant
23 prashantandsoon..

我們可以定義用戶定義的比較器: .下面的代碼可以對您有所幫助。

代碼片段:

#include<bits/stdc++.h>
using namespace std;

struct man
{
  string name;
  int priority; 
};

class comparator
{
 public:
   bool operator()(const man& a, const man& b)
   {
        return a.priority<b.priority;
   }
};

int main()
{
   man arr[5];
   priority_queue<man, vector<man>, comparator> pq;

   for(int i=0; i<3; i++)
   {
     cin>>arr[i].name>>arr[i].priority;
     pq.push(arr[i]);
   }

   while (!pq.empty())
   {
     cout<<pq.top().name<<" "<<pq.top().priority;
     pq.pop();
     cout<<endl;
   }
   return 0;
}

輸入:

蝙蝠俠 2
悟空 9
馬里奧 4

輸出

悟空 9
馬里奧 4
蝙蝠俠 2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM