使用 unordered_map 向量的 C++ 图形,在访问时添加随机数据,如 graph[i][j]

Posted

技术标签:

【中文标题】使用 unordered_map 向量的 C++ 图形,在访问时添加随机数据,如 graph[i][j]【英文标题】:C++ Graph using a vector of unordered_map, adding random data when accessed like graph[i][j] 【发布时间】:2021-04-15 17:59:25 【问题描述】:

我正在尝试浏览一个包含 2009 年 Facebook 数据的 txt 文件,并将人表示为图上的顶点,将友谊表示为边。使图表完美运行的代码。我用它来计算这个数据集中的人的平均朋友数量。但是当试图找到他们朋友的平均值时,事情变得很奇怪。当我尝试获取某个朋友的朋友数量时,该表的大小急剧增加(有一次从 10 增加到 988),它一直这样做,直到我得到一个 bad_alloc 错误并且我不知道为什么。如何在不更改图表的情况下访问元素?

 while (FacebookInfo >> V1 >> V2 >> garbage) 

        unordered_map<int, int>::const_iterator got = graph[V1].find(V2);

        if (got == graph[V1].end()) 
            graph[V1].insert(make_pair(V2, (int)graph[V1].size()));
            graph[V2].insert(make_pair(V1, (int)graph[V2].size()));
        
    


//This is the loop that breaks it
    for (int i = 1; i < 63732; i++) 

        int averageFriendsOfFriendsForV = 0;

        for (int j = 0; j < graph[i].size(); j++) 
            int friendOfFriend = graph[graph[i][j]].size(); //this is the line specifically the graph[i][j]
            averageFriendsOfFriendsForV += friendOfFriend;
        

        averageFriendsOfFriendsForV /= graph[i].size();

        totalAvg += averageFriendsOfFriendsForV;
    



编辑:想通了,仍然不确定为什么会添加数据,但是

for(auto& j : graph[i])
    int friendOfFriend = graph[j.first].size();
    etc...

修复它

【问题讨论】:

63732 似乎有点武断。如果这不仅仅是为了快速压力测试,您应该将数字转换为具有描述性名称的常数。跟随你的人会感谢你。或者至少不要用你的名字作为诅咒词。 啊谢谢Buddhima,有道理!而63732是数据集中有多少元素,我改成变量解释一下,谢谢指教! 是的,这是因为graph[i]的keys不一定是0graph[i].size() - 1之间的整数。您应该迭代实际的键。 @JonathonFord 地图神秘地获得更多元素表明您正在使用地图的operator [ ] 搜索地图。如果未找到该条目,则地图将添加该条目。这是人们在使用operator[ ] 进行地图搜索时常犯的错误。如果您的目标是确保不会无意中添加条目,请使用地图的 find() 函数。 如果结果证明键是很好的顺序而不是稀疏的,那么数组或vector 可能是更好的选择。更少的开销并且使用整数键、数组或vector 会更快地查找。 【参考方案1】:

这总是让我大吃一惊,如果你看看index operator for std::unordered_map,你会发现它会:

... perform an insertion if such key does not already exist.

所以在你怀疑的那一行循环中:

int friendOfFriend = graph[graph[i][j]].size();

您可能每次都在创建新条目,这最终变得不可能。如果您发布更多代码,可能会更容易诊断(因为我不确定graph 首先是什么类型)。

与其使用operator[],不如执行以下操作:

auto friend = graph.find(i);
if (friend == graph.end()) return;
auto other_friend = graph.find(friend->second);
if (other_friend == graph.end()) return;

或类似的东西,你明确地检查朋友的存在。

【讨论】:

以上是关于使用 unordered_map 向量的 C++ 图形,在访问时添加随机数据,如 graph[i][j]的主要内容,如果未能解决你的问题,请参考以下文章

使用 unordered_map 向量的 C++ 图形,在访问时添加随机数据,如 graph[i][j]

c++ stl unordered_map 如何打印其所有值?

C++ 返回对向量中值的引用

不支持 NodeJS 插件 Unordered_map?

从包含 unordered_maps 的 unordered_map 中提取信息

unordered_map 在使用 [] 运算符时报告“向量下标超出范围”断言