#include<iostream>
#include<list>
using namespace std;
void compute(int num)
{
list<int> L;
list<int>::iterator i;
list<int>::iterator i2;
int p;
cout<<"Enter the number of numbers\n";
cin>>p;
int a;
for(int k=1;k<=p;k++)
{
cin>>a;
L.push_back(k);
}
cout<<endl;
for(i=L.begin() ; i!=L.end() ; ++i)
{
cout<<*i<<endl;
}
long int k=1;
for(i=L.begin() ; i!=L.end() ; ++i )
{
if(k%2!=0) //This is where I try and delete values in odd positions
{
i2=L.erase(i);
}
k++;
}
for(i=L.begin() ; i!=L.end() ; ++i )
{
cout<<*i<<endl;
}
}
int main()
{
// int testcases, sailors;
//cin>>testcases;
//for(int i=1 ; i<=testcases ; i++)
{
// cin>>sailors;
}
//for(int i=1;i<=testcases;i++)
{
// int num;
//cin>>num;
//compute(num);
}
compute(0);
return 0;
}
我试图在列表中使用L.erase()函数擦除元素。但我得到一个错误说 “调试断言失败!......表达式:列表迭代器不可递增” 但我们可以增加迭代器吗?
答案 0 :(得分:1)
技术上不是这种情况。
当您使用erase()时,删除指向的节点,因此您实际上使您所在的迭代器无效。所以当你增加它时,它是未定义的行为。
最好只使用迭代器创建第二个列表到你想要删除的位置,然后你可以循环使用它们并在之后调用erase。你不会从第二个列表中删除迭代器,所以它可以工作。
这样的事情:
List<IteratorType> deleteList;
//Populate deleteList with every other element from original list.
for (List<IteratorType>::iterator iter = deleteList.begin();
iter !=deleteList.end; ++iter)
{
originalList.erase(*iter);
}
答案 1 :(得分:1)
添加到wOOte所说的内容,您可能希望使用反向迭代器来解决问题。
答案 2 :(得分:1)
erase
使作为参数传入的迭代器无效 - 因为迭代器指向的位置处的元素刚刚被删除!在同一个迭代器上,在代码中的下一个for循环中尝试增量!这就是它失败的原因。
然而,擦除它会返回一个指向新位置的迭代器,我们可以使用它;因此,从STL容器中删除内容的循环应该类似于以下内容。我用您使用的类型列表显示它,但您也可以使用例如矢量:
list<int> L;
// ...
list<int>::iterator it=L.begin();
while (it!=L.end())
{
if(eraseCondition)
{
it=L.erase(it);
}
else
{
++it;
}
}
或者,如果可能的话,最好使用std::remove_if
:
container.erase(std::remove_if(L.begin(), L.end(), predicate), L.end());
在你的情况下,使用起来很困难 - 如果不是不可能的话 - 因为predicate
需要状态信息(索引是奇数还是偶数的信息)。所以我建议使用上面提到的循环结构;请记住remove_if用于删除某个谓词返回true的所有元素的一般情况!
答案 3 :(得分:0)
对i
的调用使迭代器erase
无效;但是,在for
循环的下一次迭代中,您尝试递增它 - 这是无效的。
尝试
for(i=L.begin() ; i!=L.end() ; )
{
if(k%2!=0) //This is where I try and delete values in odd positions
{
i=L.erase(i);
} else {
++i;
}
k++;
}
相反 - 如果你不擦除,只增加迭代器(擦除基本上“前进”迭代器,因为它产生一个迭代器,跟随你擦除的元素之后的元素)。
您实际上可以利用erase
的这种行为来编写您的函数,而无需k
:
i = L.begin();
while ( i != L.end() ) {
i = L.erase( i ); // Delete one
if ( i != L.end() ) { // Skip next, if there's an element
++i;
}
}
所以你删除第一个元素,跳过第二个元素,删除第三个元素,依此类推。