0

I would like to check all Elements of an vector against each other. By checking a condition an element should be removed.

One approach was to erase the elements by nested for loops

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

but this would effect the vector and his size in runtime.

A second approach was to collect the index of b in an unordered_set but how can I delete the elements with the correspondig index in the original vector?

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

As you might expect, this approach does not work either:

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

Any help?

3
  • 1
    How are vectors declared, how does the data look like, what is the condition for removal? That info will help to give better answers. Commented Jan 4, 2019 at 12:37
  • 1
    The simplest way seems to create a new vector with the non erased elements Commented Jan 4, 2019 at 12:42
  • 1
    rs2 is a copy of rs, right ? Commented Jan 4, 2019 at 13:10

3 Answers 3

1

You can delete indices from a vector with a reverse loop in the last suggestion you made. Just make that index a vector. Let's call it toRemove.

for (int i = toRemove.size() - 1; i >= 0; i--) { rs.erase(rs.begin() + toRemove[i]); } 

Just be careful that this loop has to have a signed index. Otherwise you may underflow. You can make this "nicer" with a reverse iterator. This is just a proof of concept.

Sign up to request clarification or add additional context in comments.

Comments

1

To be as robust as possible, I would go with std::for_each. In the function performed on each object, roughly:

  • perform the calculation necessary
  • check for your condition of whether to keep the element or not
  • if you want to keep it, add it to a new out-vector, else do not

Then clear the original vector when your are done and swap the in and out vector. Move the objects to (smart!)-pointers for improved efficiency (less copying going on).

For_each combined with creating a new vector should make this very robust against potential size changes and re-allocations that might occur when using std::vector.

Comments

0

Sorry guys I changed the distance checking to the point of inserting...

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

That is much more easier than the approach before.

But thanks for the answers.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.