C ++ 14中

时间:2018-10-12 07:05:04

标签: c++ dictionary vector c++14

因此,我在Biconnected Components (BCC)中计算undirected graph,在计算之后,我的算法也在某些BCC中也包含了一些Bridge边,因此作为后处理步骤,我运行了一个循环在每个BCC(表示为vector<pair<int, int>>,每个pair<int, int>代表该BCC中的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再次是set中的pair<int, int>,其中包含我的算法找到的所有Bridge边缘。

BCCunordered_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());
}

我所做的就是在&的第一行中删除BCCList之前的for-loop。这使代码无法正常工作,并且产生的结果好像从未执行过该for-loop一样;没有删除任何BCC中的桥边缘,从而最终计算出错误的BCC。请告诉我为什么会这样?

我一直以为,如果我在bcc上有一个像unordered_map这样的迭代器,那么bcc->firstkey(这里bcc->first应该是intbcc->secondvalue(此处,bcc->second应该是vector<pair<int, int>>)。这不正确吗?为什么我必须明确指定&(参考变量)才能使代码正常工作?

这种行为也许与remove_if有关吗?​​

2 个答案:

答案 0 :(得分:6)

vector<pair<int, int>>& BCCList = (bcc->second);

在这里,BCCList是存储在bcc->second中的向量的引用(备用名称)。您对BCCList所做的任何更改实际上都是对bcc->second所做的。

vector<pair<int, int>> BCCList = (bcc->second);

在这里,BCCList是存储在bcc->second中的向量的副本。这是一个单独的对象。对其所做的更改根本不会影响bcc->second

这是一个简单的示例,应该更清楚地说明正在发生的事情:

int data = 42;
int *bcc = &data;

int &ref = *bcc;
ref = 314;

int cop = *bcc;
cop = -42;

我认为您不希望作业cop = -42;修改data。在您的代码中,情况完全相同。

答案 1 :(得分:3)

在您的原始代码中,BCCList是对BCC中某个元素的引用。您在BCCList上所做的一切,实际上都是在原始元素上完成的。

删除&时,BCCList是一个独立的值,并使用原始副本进行初始化。您对它所做的所有操作都保留在该值的局部值,并且在下一次迭代时(或在退出循环时)会丢失。