【发布时间】:2019-03-17 08:43:21
【问题描述】:
所以我在undirected graph 中计算Biconnected Components (BCC),计算后我的算法在一些密件抄送中也包含一些Bridge 边,因此作为后处理步骤,我在每个BCC 上运行一个循环(表示为vector<pair<int, int>>,每个pair<int, int> 表示该密件抄送中的edge。)我是这样做的:
auto pred = [&Bridges](pair<int, int>& edge) -> bool
{
return Bridges.find(edge) != Bridges.end();
};
for (auto bcc = BCC.begin(); bcc != BCC.end(); bcc++)
{
vector<pair<int, int>>& BCCList = (bcc->second);
BCCList.erase(remove_if(
BCCList.begin(), BCCList.end(), pred), BCCList.end());
}
Bridges 又是pair<int, int>s 的set,包含我的算法找到的所有桥边。
BCC 是 unordered_map<int, vector<pair<int, int>>>。
上面的代码按预期工作,删除了之前可能存在于 BCC 向量中的任何 Bridge 边缘。但是,如果我稍作改动并这样做:
auto pred = [&Bridges](pair<int, int>& edge) -> bool
{
return Bridges.find(edge) != Bridges.end();
};
for (auto bcc = BCC.begin(); bcc != BCC.end(); bcc++)
{
vector<pair<int, int>> BCCList = (bcc->second);
BCCList.erase(remove_if(
BCCList.begin(), BCCList.end(), pred), BCCList.end());
}
我所做的只是在for-loop 的第一行中删除BCCList 之前的&。这使得代码无法工作,并产生一个结果,好像这个 for-loop 从未执行过;任何 BCC 中的桥边都不会被删除,因此最终会计算错误的 BCC。请告诉我为什么会这样?
我一直认为,如果我在unordered_map 上有一个类似bcc 的迭代器,那么bcc->first 就是key(这里,bcc->first 应该是一个int)而bcc->second 是value(这里,bcc->second 应该是 vector<pair<int, int>>)。这不正确吗?为什么我必须明确指定 &(引用变量)才能使代码正常工作?
这种行为可能与remove_if 有关吗?
【问题讨论】:
-
删除引用类型最终会创建每个项目的副本,通过您的 remove-if 将其修剪掉,然后丢弃所有工作。原始容器不受影响。
标签: c++ dictionary vector c++14