C++ вложенный в цикл с удаляемыми элементами
Я хотел бы проверить все элементы вектора друг против друга. Проверяя условие, элемент должен быть удален.
Один из подходов заключался в удалении элементов с помощью вложенных циклов
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, но как я могу удалить элементы с соответствующим индексом в исходном векторе?
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 ответа
Вы можете удалить индексы из вектора с обратной петлей в последнем предложенном вами предложении. Просто сделай это index
вектор. Давайте назовем это toRemove
,
for (int i = toRemove.size() - 1; i >= 0; i--)
{
rs.erase(rs.begin() + toRemove[i]);
}
Просто будьте осторожны, чтобы этот цикл имел подписанный индекс. В противном случае вы можете потерять. Вы можете сделать это "лучше" с помощью обратного итератора. Это просто доказательство концепции.
Чтобы быть максимально устойчивым, я бы использовал std::for_each. В функции, выполняемой для каждого объекта, примерно:
- выполнить расчет необходимо
- проверьте ваше состояние, сохранять ли элемент или нет
- если вы хотите сохранить его, добавьте его в новый out-vector, иначе не
Затем очистите исходный вектор, когда закончите, и поменяйте местами вектор входа и выхода. Переместите объекты в (умные!)- указатели для повышения эффективности (меньше копирования).
For_each в сочетании с созданием нового вектора должен сделать это очень устойчивым к потенциальным изменениям размера и перераспределениям, которые могут произойти при использовании std::vector.
Извините, ребята, я изменил проверку расстояния до точки вставки...
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);
}
}
}
}
Это намного проще, чем предыдущий подход.
Но спасибо за ответы.