Дано
std::vector<double> a;
std::vector<int> ind;
где ind
является 1отсортировано в порядке возрастания.
Я хочу сделать эквивалент следующего:
for (auto it=ind.rbegin();it!=ind.rend();it++) a.erase(a.begin() + *it);
Я придумал это:
for (auto it=ind.begin();it!=ind.end();it++)
a[*it] = std::numeric_limits<double>::max();
std::erase(std::remove(a.begin(),a.end(),std::numeric_limits<double>::max()),a.end());
Это очень быстро, но не правильно использовать std :: numeric_limits :: max () в качестве флага в этом контексте.
Конечно, чувства не должны играть слишком много в уравнении … четкое сравнение двойных значений в std :: remove безопасно, и на практике этот вектор никогда не возникнет в этом в рабочем приложении, поэтому все должно быть в порядке, нет?
Есть мысли по этому поводу?
1) Ссылка комментарий ОП. Альф
Давайте посмотрим на ваш «базовый» код, который вы говорите, что хотите сделать «эквивалент»:
std::vector<double> a;
std::vector<int> ind;
for (auto it = ind.rbegin(); it != ind.rend(); it++)
a.erase(a.begin() + *it);
Из этого мы получаем то, что ind
вектор индексов в a
которые должны быть удалены, и что они отсортированы по возрастанию. Эти индексы должны быть удалены из a
, Я предполагаю, что ваша цель — сделать это эффективно с точки зрения пространства и времени.
Если вы думаете об этом с точки зрения минимального количества требуемых операций, вы должны сдвинуть многие / большинство / все элементы в a
чтобы стереть те, которые указаны ind
, Ты не хочешь erase()
несколько раз, потому что это означает смещение некоторых элементов более одного раза. Одно оптимальное решение (в общем случае не навязывание особых требований к значениям в a
) выглядит так:
size_t slow = 0; // where we are currently copying "to"std::vector<int> inditer = ind.begin();
for (size_t fast = 0; fast != a.size(); ++fast) {
if (inditer != ind.end() && *inditer == fast) {
// "remove" this element by ignoring it
++inditer;
} else {
a[slow] = a[fast];
++slow;
}
}
a.resize(slow);
Теперь вы могли бы переформулировать это, используя алгоритмы STL и пользовательский предикат (функтор), который запоминает свою «текущую» позицию в ind
, но это не будет намного меньше кода, и это может быть сложнее понять.