[英]C++ map using pair as key
我正在使用一個地圖(這似乎是上一個問題之后的最佳實現,帶有一對密鑰,作為傳入消息的'容器',可以根據sourceID和優先級進行排序,即密鑰:(sourceID,priority)指向一個int value。處理將在此地圖上“發生”。
我剛剛遇到一個問題 - 我需要做一些像這樣的偽代碼來隨后檢索消息:
map<pair<int, int>, int> mymap;
if (!mymap[make_pair(nodeID,i)].empty()) //i refers to all the priority levels
//processing occurs here to retrieve a value
但我似乎無法輕易做到。 有沒有辦法在不運行迭代器的情況下執行此操作,例如for (i = 0; i <priority ; i++)
? 我知道,如果我使用等效的vector<vector<int>>
我可以很容易地做到這一點,但是地圖對我的程序來說效果更好。
編輯:
消息按(sourceID,優先級)排序到映射中,然后在通過(destID,優先級)映射到另一個映射之前進行處理。 我需要檢查那里有可用於任何特定destID的消息,無論優先級如何,所以我正在尋找一種簡單的方法來檢查這一點。
我知道如果我使用vector<vector<int>>
,我將能夠執行類似node[2].empty()
,如果我想檢查節點2沒有可用的消息。 地圖有等價物嗎?
如果我理解正確,你想要一個方便的方法來確定地圖有多少條目(node_id,i)
,其中node_id
是固定的, i
可以是任何東西。
如果這種理解是正確的,你可以利用這樣一個事實,即你的地圖中的排序是基於std::less<std::pair<int,int>>
定義的排序,默認情況下是字典排序。 換句話說,node-id將用作主要排序標准,而該對的第二個元素將用作次要排序標准。
因此,您可以使用map的lower_bound
和upper_bound
函數來確定給定node-id的條目范圍,如下所示(C ++ 11代碼,但可以轉換為C ++ 03):
std::ptrdiff_t num_per_node(const mymap &map, const int node_id)
{
using std::distance;
static constexpr int min = std::numeric_limits<int>::min();
static constexpr int max = std::numeric_limits<int>::max();
auto lo = map.lower_bound({node_id,min});
auto hi = map.upper_bound({node_id,max});
return distance(lo,hi);
}
上面定義的函數返回給定node-id node_id
的映射map
的條目數。
所以你的偽代碼變成:
if (num_per_node(mymap,nodeID) > 0)
該函數具有對數復雜度,這明顯(漸近)比迭代所有優先級值更好。
請注意,這只能起作用,因為對的元素是int
,因此很容易建立最小值和最大值。 同樣,它也只能起作用,因為詞典排序。 如果對地圖使用自定義比較器功能,則此方法將不再起作用,是否可以找到相應方法取決於比較器的確切定義。
這是一個GIT-gist,其中有一個完整的示例,演示了如何使用該函數: https : //gist.github.com/jogojapan/5027365
僅僅基於@jogojapan所做的事情,我已經將其改編為不使用C ++ 11(因為我沒有使用它),並將其留在這里作為參考。 不確定它做了他所做的一切 ,但對我來說足夠有效
#include <iostream>
#include <utility>
#include <limits>
#include <map>
using namespace std;
std::ptrdiff_t num_per_node(const map<pair<int, int>, int> &map, const int node_id)
{
using std::distance;
static int min = std::numeric_limits<int>::min();
static int max = std::numeric_limits<int>::max();
auto lo = map.lower_bound(make_pair(node_id,min));
auto hi = map.upper_bound(make_pair(node_id,max));
return distance(lo,hi);
}
int main() {
map<pair<int, int>, int> m;
m.insert(make_pair(make_pair(1,3),1));
m.insert(make_pair(make_pair(3,4),2));
m.insert(make_pair(make_pair(3,5),3));
m.insert(make_pair(make_pair(3,9),4));
m.insert(make_pair(make_pair(4,2),5));
m.insert(make_pair(make_pair(4,3),6));
m.insert(make_pair(make_pair(5,1),7));
m.insert(make_pair(make_pair(8,2),8));
for (int node_id = 0 ; node_id < 10 ; ++node_id)
std::cout << "node-id " << node_id << ": " << num_per_node(m,node_id) << '\n';
return 0;
}
哪個正確返回
node-id 0: 0
node-id 1: 1
node-id 2: 0
node-id 3: 3
node-id 4: 2
node-id 5: 1
node-id 6: 0
node-id 7: 0
node-id 8: 1
node-id 9: 0
其中一個可能的解決方案是使用2個嵌套映射:
typedef std::map<int,int> priorities;
typedef std::map<int,priorities> messages;
查找給定sourceId是否有任何消息,當您需要查找具有給定sopurceId和優先級的消息時,任何優先級對於2次查找的價格變得微不足道。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.