Обход мультимножества от нижней границы
Я хочу начать с итератора low_bound моего целевого значения в мультимножестве, затем удалить все его вхождения и продолжить переход к следующим значениям того же мультимножества, я делаю что-то вроде...
multiset<int>s={....};
auto it=s.lower_bound(target);
while(it!=s.end()){
if(s.find(target)!=s.end())
it=s.erase(target);
else it++;
}
Но у меня выдает ошибку...
Line 36: Char 12: error: no viable overloaded '='
it4=x.erase(99);
~~~^~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_tree.h:326:12: note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'std::set<int, std::less<int>, std::allocator<int>>::size_type' (aka 'unsigned long') to 'const std::_Rb_tree_const_iterator<int>' for 1st argument
struct _Rb_tree_const_iteratorrgument
Есть ли разница в итераторах s.lower_bound(target) и s.erase(target)? Мне особенно нужно продолжать перемещение таким образом, поскольку я знаю другой способ продолжать поиск и удаление цели до тех пор, пока ее больше нельзя будет найти в наборе.
1 ответ
Аstd::set
может иметь только один экземпляр любого значения, поэтому однократный вызов удаляет все возможные экземпляры этого значения. Нет необходимости сначала вызывать low_bound или что-то в этом роде. Например:
int main(){
std::set<int> x = { 1, 2, 3, 4, 5};
x.erase(2);
for (auto const &p : x)
std::cout << p << " ";
}
Производит:
1 3 4 5
Если вы хотите сохранить несколько копий одного и того же значения, это будетstd::multiset
вместо. В этом случае, если вы хотите удалить все копии определенного значения, наиболее простым способом, вероятно, будет использованиеstd::equal_range
:
#include <set>
#include <iostream>
int main() {
std::multiset<int> s { 1, 2, 3, 4 ,4, 5, 2, 1, 3};
auto p = s.equal_range(2);
s.erase(p.first, p.second);
for (auto const & v : s)
std::cout << v << " ";
std::cout << "\n";
}
Результат:
1 1 3 3 4 4 5
Но вы также можете заметить, что в этом случае нам по-прежнему не нужно указывать диапазон для прохождения. Мы по-прежнему можем просто указать значение, которое нужно стереть, и все его экземпляры будут удалены:
#include <set>
#include <iostream>
int main() {
std::multiset<int> s { 1, 2, 3, 4 ,4, 5, 2, 1, 3};
s.erase(2);
for (auto const & v : s)
std::cout << v << " ";
std::cout << "\n";
}
[Тот же результат, что и выше]
было бы полезно, если бы (например) мы хотели стереть все экземпляры этого значения в наборе, кроме одного. В этом случае мы могли бы (например) вызватьequal_range
и либо увеличить его.first
или уменьшить его.second
, тогда позвониerase
, стирая все это значение, кроме одного.