Здравствуйте, уважаемые господа!
Подскажите, пожалуйста, как правильно реализовать удаление елемента из вектора (в цыкле).
std::vector <char> S;
std::vector <char>::iterator it;
int main()
{
for (it=S.begin()+1; it!=S.end()-1; it++)
if (*(it-1) == *(it+1)) S.erase(it);
return 0;
}
Я предлагаю такой вариант:
it=S.begin()+1;
while (it!=S.end()-1)
{
if (*(it-1) == *(it+1))
it = S.erase(it);
else
it++;
}
А что скажут эксперты?
Заранее благодарю, за внимание.
Здравствуйте, Бадян, Вы писали:
<...>
Если хочешь удалить все одинаковые подрядидущие элементы, то можно воспользоваться std::unique :
std::vector<char> S;
S.erase(std::unique(S.begin(),S.end()),S.end());
Я что-то не очень понял, что требуется, так что извините, если неправ.
#include <algorithm>
////
std::vector<int>a(30);
///
std::sort(a.begin(),a.end());
std::vector<int>::iterator v_it = std::unique(a.begin(),a.end());
a.erase(v_it,a.end());
Здравствуйте, Бадян, Вы писали:
Б>Здравствуйте, уважаемые господа!
Б>Подскажите, пожалуйста, как правильно реализовать удаление елемента из вектора (в цыкле).
Не совсем ясен критерий удаления элементов. Судя по коду, вы хотели удалить элементы находящиеся между двумя эквивалентными. Я воссоздал логику работы вашего алгоритма и привожу с точки зрения быстродействия (за счет увеличения расхода памяти) более эффективный вариант, поскольку исключается избыточное копирование элементов выполняемое после каждого вызова erase (O(n)):
#include <iostream>
#include <vector>
#include <algorithm>
template<typename T>
void foo(std::vector<T> &v)
{
typedef std::vector<T> seq;
size_t size = 0;
if( (size = v.size()) < 1 )
return;
seq r; r.reserve(size);
T c = v[0];
for(size_t i = 1; i < (size-1); ++i)
{
r.push_back(c);
if (c == v[i+1])
++i;
else
c = v[i];
}
r.push_back(v[size-1]);
v.swap(r);
}
int main(void)
{
typedef std::vector<int> seq;
int a[] = {10, 3, 10, 3, 10, 5, 6};
seq v(a, a + sizeof(a)/sizeof(a[0]));
std::ostream_iterator<int> oo(std::cout, " ");
std::cout << "before: ";
std::copy(v.begin(), v.end(), oo);
std::cout << std::endl;
foo(v);
std::cout << "after: ";
std::copy(v.begin(), v.end(), oo);
std::cout << std::endl;
return 0;
}
А так, если критерий удаления элемента выражается предикатом (эквивалентность — частный случай), то наиболее предпочтительным способом удаления элементов вектора является алгоритм std::remove[_if], считая вектор не упорядоченным:
//
// удалить все вхождения 10
//
v.erase(std::remove(v.begin(), v.end(), 10), v.end());