我正在使用地图(这似乎是previous question之后的最佳实现,带有一对密钥,作为传入消息的“容器”,可根据sourceID和优先级进行排序,即:key:(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没有可用的消息。是否有相应的地图?
答案 0 :(得分:3)
如果我理解正确,您需要一种方便的方法来确定地图有(node_id,i)
个条目的数量,其中node_id
是固定的,i
可以是任何内容。
如果这种理解是正确的,你可以利用这样一个事实,即地图内的排序是基于std::less<std::pair<int,int>>
定义的排序,默认情况下是字典排序。换句话说,node-id将用作主要的排序标准,而该对的第二个元素将用作次要排序标准。
因此,您可以使用映射的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 map
的地图node_id
中的条目数。
所以你的伪代码变成了:
if (num_per_node(mymap,nodeID) > 0)
该函数具有对数复杂度,明显(渐近)比迭代所有优先级值更好。
请注意,这仅适用,因为您的对的元素是int
,因此很容易建立最小值和最大值。同样,它也只能起作用,因为词典排序。如果对地图使用自定义比较器功能,此方法将不再起作用,是否可以找到相应的方法取决于比较器的确切定义。
这是一个GIT-gist,其中有一个完整的示例,演示了如何使用该函数:https://gist.github.com/jogojapan/5027365
答案 1 :(得分:1)
仅仅基于@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 :(得分:0)
可能的解决方案之一可能是使用2个嵌套地图:
typedef std::map<int,int> priorities;
typedef std::map<int,priorities> messages;
查找给定sourceId是否有任何消息,当您需要查找具有给定sopurceId和优先级的消息时,任何优先级对于2次查找的价格都变得微不足道。