簡體   English   中英

使用pair作為鍵的C ++映射

[英]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_boundupper_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.

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