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

问题描述 投票:1回答:3

我正在使用一个地图(这似乎是previous question之后的最佳实现,带有一对密钥,作为传入消息的'容器',可以根据sourceID和优先级排序,即密钥:(sourceID,priority)指向int处理将在此地图上“发生”。

我刚刚遇到一个问题 - 我需要做一些像这样的伪代码来随后检索消息:

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没有可用的消息。地图有等价物吗?

c++ dictionary containers std-pair
3个回答
3
投票

如果我理解正确,你想要一个方便的方法来确定地图有多少条目(node_id,i),其中node_id是固定的,i可以是任何东西。

如果这种理解是正确的,你可以利用这样一个事实,即地图内的排序是基于std::less<std::pair<int,int>>定义的排序,lower_bound默认是字典排序。换句话说,node-id将用作主要排序标准,而该对的第二个元素将用作次要排序标准。

因此,您可以使用映射的upper_boundstd::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的条目范围,如下所示(C ++ 11代码,但可以转换为C ++ 03):

map

上面定义的函数返回给定node-id node_id的映射if (num_per_node(mymap,nodeID) > 0) 中的条目数。

所以你的伪代码变成:

int

该函数具有对数复杂度,这明显(渐近)比迭代所有优先级值更好。

请注意,这只能起作用,因为您的对的元素是https://gist.github.com/jogojapan/5027365,因此很容易建立最小值和最大值。同样,它也只能起作用,因为词典排序。如果对地图使用自定义比较器功能,则此方法将不再起作用,是否可以找到相应方法取决于比较器的确切定义。

这是一个GIT-gist,其中有一个完整的例子,演示了如何使用该函数:#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; }


1
投票

仅仅基于@jogojapan所做的事情,我已经将其改编为不使用C ++ 11(因为我没有使用它),并将其留在这里作为参考。不确定它做了他所做的一切,但对我来说足够有效

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

哪个正确返回

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

0
投票

其中一个可能的解决方案是使用2个嵌套映射:

qazxswpoi

查找给定sourceId是否有任何消息,当您需要查找具有给定sopurceId和优先级的消息时,任何优先级对于2次查找的价格变得微不足道。

© www.soinside.com 2019 - 2024. All rights reserved.