C ++嵌套有擦除元素的循环

时间:2019-01-04 12:29:45

标签: c++ vector nested-loops erase erase-remove-idiom

我想相互比较向量的所有元素。通过检查条件,应删除一个元素。

一种方法是通过嵌套for循环擦除元素

for (int a = 0; a < rs.size(); a++)
{
    Point A = rs[a];

    for (int b = 1; b <= rs.size(); b++)
    {
        Point B = rs2[b];
        float distance = sqrt(pow(B.x - A.x, 2) + pow(B.y - A.y, 2) * 1.0);

        if (distance < 10.0)
        {
            if (distance > 0)
            {
                rs.erase(rs.begin() + b);
            }
        }
    }
}

但这会在运行时影响矢量及其大小。

第二种方法是在无序集合中收集b的索引,但是如何删除原始向量中具有对应索引的元素?

unordered_set<int> index;

for (int a = 0; a < rs.size(); a++)
{
    Point A = rs[a];

    for (int b = 0; b < rs.size(); b++)
    {
        Point B = rs2[b];
        float distance = sqrt(pow(B.x - A.x, 2) + pow(B.y - A.y, 2) * 1.0);

        if (distance < 10.0)
        {
            if (distance > 0)
            {
                index.insert(b);
            }
        }
    }
}

如您所料,这种方法也不起作用:

for (const int& idx : index)
{
    rs.erase(rs.begin() + idx);
}

有帮助吗?

3 个答案:

答案 0 :(得分:1)

您可以在上一个建议中使用反向循环从向量中删除索引。只需将getSettings(){ conn.query("SELECT * FROM tb_settings ORDER BY id", (err, results) => { if (err){ console.log(err); } }); }, getParams(req, params){ return Object.assign({}, { menus: req.menus, user: req.session.user, }, params); 设为向量即可。我们称之为index

toRemove

请小心,此循环必须具有带符号的索引。否则您可能会下溢。您可以使用反向迭代器使此“更精细”。这只是概念的证明。

答案 1 :(得分:1)

为了尽可能强大,我将使用std :: for_each。在对每个对象执行的功能中,大致:

  • 执行必要的计算
  • 检查是否保留该元素的条件
  • 如果要保留它,请将其添加到新的向量中,否则不要

然后在完成操作后清除原始向量,并交换输入和输出向量。将对象移至(智能!)指针,以提高效率(减少复制工作)。

For_each与创建一个新的向量相结合,应该使它非常健壮,以防止使用std :: vector时可能发生的大小更改和重新分配。

答案 2 :(得分:0)

对不起,我将距离检查更改为插入...

vector<Point> rois;
for (int y = 0; y < result.rows; y++)
{
    for (int x = 0; x < result.cols; x++)
    {
        float qt = result.at<float>(y, x);

        if (qt >= threshVal)
        {
            Point A = Point(x, y);

            bool isNear = true;

            if (rois.size() > 0)
            {
                for (Point &P : rois)
                {
                    float distance = sqrt(pow(P.x - A.x, 2) + pow(P.y - A.y, 2) * 1.0);

                    if (distance < 10.0)
                    {
                        isNear = false;
                        break;
                    }
                }
                if (isNear)
                {
                    rois.push_back(A);
                }
            }
            else
            {
                rois.push_back(A);
            }
        }
    }
}

这比以前的方法容易得多。

但是感谢您的回答。