簡體   English   中英

排序集沒有嚴格的弱排序

[英]Sorted set without a strict weak ordering

我有以下問題:考慮這種(簡化的)結構:

struct Task {
    int priority;
    std::string description;
    // Some other fields
};

現在,我要擁有一組所有任務並對其進行一些處理。 因此,我有一個相等運算符,該運算符檢查每個元素是否相等。

bool isEqual(const Task& lhs, const Task& rhs) {
    return lhs.priority == rhs.priority &&
        lhs.description == rhs.description &&
        // Some other fields
        ;
}

為此,我使用了std :: unordered_set,效果很好。

但是現在我希望這些任務按集合中的優先級排序(以獲得最高優先級的任務)。 顯然,這對於std :: unordered_set是不可能的,因此我嘗試了使用以下較少運算符的std :: set:

bool lessTask(const Task& lhs, const Task& rhs) {
    return lhs.priority < rhs.priority;
}

但這意味着嚴格的弱排序,當優先級相等時,兩個任務是相等的,而我不希望這樣做(我想維護我的isEqual方法以進行相等性檢查)。

什么是完成一組任務的最佳方法,在該方法中,我可以非常快速地插入元素並且沒有重復的條目(由isEqual函數定義),但是能夠真正快速地檢索優先級最高的任務?
我沒有綁定到任何特定的STL容器,但不想使用任何第三方庫(甚至不使用boost)。

在地圖上放置元素時,通常需要將該類的所有成員添加到less 否則它將無法正常工作。 當我不得不創建一個包含約15種不同的,不斷變化的類的系統時,這是一個巨大的挑戰,而那時我真的開始錯過了編譯時反射。

另外,您可以使用優先級隊列std::make_heap )來代替映射。 優先堆不關心相等性,它將首先為您提供具有最高優先級的任務。

首先寫get_tie

// auto or decltype(auto)
auto get_tie(const Task& task) {
  return std::tie(lhs.priority, lhs.description, /* some other fields */ );
}

在C ++ 11中,您必須使用->decltype尾隨返回類型來重復主體,或者使用宏來避免重復:

#define RETURNS(...) decltype(__VA_ARGS__) { return __VA_ARGS__; }
auto get_tie(const Task& task)->
RETURNS( std::tie(lhs.priority, lhs.description, /* some other fields */ ) )

一旦我們有了一個簡單的get_tie ,您的問題就消失了。

bool isEqual( Task const& lhs, Task const& rhs ) {
  return get_tie(lhs)==get_tie(rhs);
}
bool isLess( Task const& lhs, Task const& rhs ) {
  return get_tie(lhs) < get_tie(rhs);
}

只需將isLess傳遞給std::set ,或使用isLess構建一個std::vectorstd::sort isLess

現在,如果你的比較並沒有真正在原始工作tie引用,則可能必須更換get_tie與更復雜的東西。

暫無
暫無

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

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