简体   繁体   English

使用pair作为键的C ++映射

[英]C++ map using pair as key

I am using a map (which seemed the best implementation after a previous question , with a pair key, as a 'container' for incoming messages that can be sorted according to sourceID and priority ie key: (sourceID, priority) which points to an int value. Processing will happen 'on' this map. 我正在使用一个地图(这似乎是上一个问题之后的最佳实现,带有一对密钥,作为传入消息的'容器',可以根据sourceID和优先级进行排序,即密钥:(sourceID,priority)指向一个int value。处理将在此地图上“发生”。

I've just come against a problem - I need to do something like this pseudo code to subsequently retrieve messages: 我刚刚遇到一个问题 - 我需要做一些像这样的伪代码来随后检索消息:

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

but I can't seem to do it easily. 但我似乎无法轻易做到。 Is there a way to do this simply without running an iterator eg for (i = 0; i <priority ; i++) ? 有没有办法在不运行迭代器的情况下执行此操作,例如for (i = 0; i <priority ; i++) I know that if I used an equivalent vector<vector<int>> I would be able to do this easily, but a map works better for my program at the moment. 我知道,如果我使用等效的vector<vector<int>>我可以很容易地做到这一点,但是地图对我的程序来说效果更好。

edit: 编辑:

The messages are sorted into the map by (sourceID, priority level), and then processed before being mapped into another map by (destID, priority level). 消息按(sourceID,优先级)排序到映射中,然后在通过(destID,优先级)映射到另一个映射之前进行处理。 I need to check there there are messages available for any particular destID, regardless of priority level, so I am looking for an easy way to check this. 我需要检查那里有可用于任何特定destID的消息,无论优先级如何,所以我正在寻找一种简单的方法来检查这一点。

I know that if I use a vector<vector<int>> , I will be able to do something like node[2].empty() , if I want to check that node 2 has no available messages. 我知道如果我使用vector<vector<int>> ,我将能够执行类似node[2].empty() ,如果我想检查节点2没有可用的消息。 Is there an equivalent for maps? 地图有等价物吗?

If I understand things correctly, you'd like a convenient way to determine how many entries (node_id,i) the map has, where node_id is fixed and i can be anything. 如果我理解正确,你想要一个方便的方法来确定地图有多少条目(node_id,i) ,其中node_id是固定的, i可以是任何东西。

If this understanding is correct, you can make use of the fact that the ordering inside your map is based on the ordering defined by std::less<std::pair<int,int>> , which by default is the lexicographical ordering. 如果这种理解是正确的,你可以利用这样一个事实,即你的地图中的排序是基于std::less<std::pair<int,int>>定义的排序,默认情况下是字典排序。 In other words, the node-id will be used as the main sorting criterion, whereas the second element of the pair will be used as secondary sorting criterion. 换句话说,node-id将用作主要排序标准,而该对的第二个元素将用作次要排序标准。

You can therefore use the lower_bound and upper_bound functions of the map to determine the range of entries for a given node-id as follows (C++11 code, but can be converted to C++03): 因此,您可以使用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);
}

The function defined above returns the number of entries there are in the map map for the given node-id node_id . 上面定义的函数返回给定node-id node_id的映射map的条目数。

So your pseudo-code becomes: 所以你的伪代码变成:

if (num_per_node(mymap,nodeID) > 0)

The function has logarithmic complexity, which is clearly (asymptotically) better than iterating through all priority values. 该函数具有对数复杂度,这明显(渐近)比迭代所有优先级值更好。

Note that this only works because the elements of your pairs are int , so it is readily possible to establish minimum and maximum values. 请注意,这只能起作用,因为对的元素是int ,因此很容易建立最小值和最大值。 Again, it also only works because of the lexicographical ordering. 同样,它也只能起作用,因为词典排序。 If you use a customised comparator function with your map, this method will no longer work, and whether a corrsponding method can be found depends on how exactly your comparator is defined. 如果对地图使用自定义比较器功能,则此方法将不再起作用,是否可以找到相应方法取决于比较器的确切定义。

Here is a GIT-gist with a complete example that demonstrates how the function can be used: https://gist.github.com/jogojapan/5027365 这是一个GIT-gist,其中有一个完整的示例,演示了如何使用该函数: https//gist.github.com/jogojapan/5027365

Just to build on what @jogojapan has done, I've adapted it to not use C++11 (because I'm not using it), and leaving it here for reference. 仅仅基于@jogojapan所做的事情,我已经将其改编为不使用C ++ 11(因为我没有使用它),并将其留在这里作为参考。 Not sure it does everything his does, but works sufficiently for me 不确定它做了他所做的一切 ,但对我来说足够有效

#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;
  }

which correctly returns 哪个正确返回

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

One of the possible solution could be using 2 nested maps: 其中一个可能的解决方案是使用2个嵌套映射:

typedef std::map<int,int> priorities;
typedef std::map<int,priorities> messages;

Find if there is any message for given sourceId and any priority becomes trivial for price of 2 lookups when you need to find message with given sopurceId and priority. 查找给定sourceId是否有任何消息,当您需要查找具有给定sopurceId和优先级的消息时,任何优先级对于2次查找的价格变得微不足道。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM