中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在C++項目中利用priority_queue自定義排序

發布時間:2021-03-04 14:17:49 來源:億速云 閱讀:265 作者:Leah 欄目:開發技術

這篇文章給大家介紹怎么在C++項目中利用priority_queue自定義排序,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

首先,無論 priority_queue 中存儲的是基礎數據類型(int、double 等),還是 string 類對象或者自定義的類對象,都可以使用函數對象的方式自定義排序規則。例如:

#include<iostream>
#include<queue>
using namespace std;
//函數對象類
template <typename T>
class cmp
{
public:
  //重載 () 運算符
  bool operator()(T a, T b)
  {
    return a > b;
  }
};
int main()
{
  int a[] = { 4,2,3,5,6 };
  priority_queue<int,vector<int>,cmp<int> > pq(a,a+5);
  while (!pq.empty())
  {
    cout << pq.top() << " ";
    pq.pop();
  }
  return 0;
}

運行結果為:
2 3 4 5 6

注意,C++ 中的 struct 和 class 非常類似,前者也可以包含成員變量和成員函數,因此上面程序中,函數對象類 cmp 也可以使用 struct 關鍵字創建:

struct cmp
{
  //重載 () 運算符
  bool operator()(T a, T b)
  {
    return a > b;
  }
};

可以看到,通過在 cmp 類(結構體)重載的 () 運算符中自定義排序規則,并將其實例化后作為 priority_queue 模板的第 3 個參數傳入,即可實現為 priority_queue 容器適配器自定義比較函數。

除此之外,當 priority_queue 容器適配器中存儲的數據類型為結構體或者類對象(包括 string 類對象)時,還可以通過重載其 > 或者 < 運算符,間接實現自定義排序規則的目的。

注意,此方式僅適用于 priority_queue 容器中存儲的為類對象或者結構體變量,也就是說,當存儲類型為類的指針對象或者結構體指針變量時,此方式將不再適用,而只能使用函數對象的方式。

要想徹底理解這種方式的實現原理,首先要搞清楚 std::less<T> 和 std::greater<T> 各自的底層實現。實際上,<function> 頭文件中的 std::less<T> 和 std::greater<T> ,各自底層實現采用的都是函數對象的方式。比如,std::less<T> 的底層實現代碼為:

template <typename T>
struct less {
  //定義新的排序規則
  bool operator()(const T &_lhs, const T &_rhs) const {
    return _lhs < _rhs;
  }
};

std::greater<T> 的底層實現代碼為:

template <typename T>
struct greater {
  bool operator()(const T &_lhs, const T &_rhs) const {
    return _lhs > _rhs;
  }
};

可以看到,std::less<T> 和 std::greater<T> 底層實現的唯一不同在于,前者使用 < 號實現從大到小排序,后者使用 > 號實現從小到大排序。

那么,是否可以通過重載 < 或者 > 運算符修改 std::less<T> 和 std::greater<T> 的排序規則,從而間接實現自定義排序呢?答案是肯定的,舉個例子:

#include<queue>
#include<iostream>
using namespace std;
class node {
public:
  node(int x = 0, int y = 0) :x(x), y(y) {}
  int x, y;
};
//新的排序規則為:先按照 x 值排序,如果 x 相等,則按 y 的值排序
bool operator < (const node &a, const node &b) {
  if (a.x > b.x) return 1;
  else if (a.x == b.x)
    if (a.y >= b.y) return 1;
  return 0;
}
int main() {
  //創建一個 priority_queue 容器適配器,其使用默認的 vector 基礎容器以及 less 排序規則。
  priority_queue<node> pq;
  pq.push(node(1, 2));
  pq.push(node(2, 2));
  pq.push(node(3, 4));
  pq.push(node(3, 3));
  pq.push(node(2, 3));
  cout << "x y" << endl;
  while (!pq.empty()) {
    cout << pq.top().x << " " << pq.top().y << endl;
    pq.pop();
  }
  return 0;
}

輸出結果為:
x y
1 2
2 2
2 3
3 3
3 4

可以看到,通過重載 < 運算符,使得 std::less<T> 變得適用了。
讀者還可以自行嘗試,通過重載 > 運算符,賦予 std::greater<T> 和之前不同的排序方式。

當然,也可以以友元函數或者成員函數的方式重載 > 或者 < 運算符。需要注意的是,以成員函數的方式重載 > 或者 < 運算符時,該成員函數必須聲明為 const 類型,且參數也必須為 const 類型,至于參數的傳值方式是采用按引用傳遞還是按值傳遞,都可以(建議采用按引用傳遞,效率更高)。

例如,將上面程序改為以成員函數的方式重載 < 運算符:

class node {
public:
  node(int x = 0, int y = 0) :x(x), y(y) {}
  int x, y;
  bool operator < (const node &b) const{
    if ((*this).x > b.x) return 1;
    else if ((*this).x == b.x)
      if ((*this).y >= b.y) return 1;
    return 0;
  }
};

同樣,在以友元函數的方式重載 < 或者 > 運算符時,要求參數必須使用 const 修飾。例如,將上面程序改為以友元函數的方式重載 < 運算符。例如:

class node {
public:
  node(int x = 0, int y = 0) :x(x), y(y) {}
  int x, y;
  friend bool operator < (const node &a, const node &b);
};
//新的排序規則為:先按照 x 值排序,如果 x 相等,則按 y 的值排序
bool operator < (const node &a, const node &b){
  if (a.x > b.x) return 1;
  else if (a.x == b.x)
    if (a.y >= b.y) return 1;
  return 0;
}

關于怎么在C++項目中利用priority_queue自定義排序就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

霞浦县| 张家川| 五大连池市| 河间市| 隆子县| 广安市| 沅江市| 平顺县| 青田县| 花莲县| 蚌埠市| 龙州县| 乳源| 翁牛特旗| 庆城县| 淮北市| 鄂州市| 蒲城县| 科技| 清河县| 永定县| 马龙县| 林周县| 馆陶县| 汤原县| 马山县| 莱州市| 阜南县| 五寨县| 凤翔县| 崇义县| 土默特右旗| 连山| 泰和县| 谢通门县| 古蔺县| 鄂托克前旗| 塘沽区| 长泰县| 宜川县| 彭水|