删除无法正常工作

时间:2011-01-24 11:11:05

标签: c++ algorithm templates stl c++11

std::vector<int> v = {1,2,3,4,5};
auto i = std::remove(v.begin(),v.end(),3); 
for(auto j = v.begin(); j!= v.end();++j)
   std::cout << *j;

实际输出:12455

额外的5来自哪里?

所需的输出:1245

如何实现同样的目标?

我实际上想要改变矢量的大小,Prasoon saurav给出的答案看起来是正确的

4 个答案:

答案 0 :(得分:25)

remove doesnt actually remove the elements

  

[first, last)范围内移除所有等于value的元素。也就是说,remove返回迭代器new_last,使得范围[first, new_last)不包含等于value的元素。 1范围[new_last, last)中的迭代器都仍可解除引用,但它们指向的元素是未指定。删除是稳定的,这意味着不等于值的元素的相对顺序不变。

std::remove算法仅使用一对前向迭代器,并且通常对底层容器一无所知。

您需要使用erase-remove惯用法实际删除元素,即eraseremove

组合
auto i = std::remove(v.begin(),v.end(),3);
v.erase(i,v.end());
for(auto j = v.begin(); j!= v.end();++j)
   std::cout << *j;

答案 1 :(得分:5)

再次阅读std::remove的文档。

该函数不会从容器中删除元素(事实上,它甚至知道涉及容器,因为它只看到迭代器),它只是按顺序移动值,返回一个新的迭代器i,使所有间隔[ begin .. i [包含原始顺序中所有未删除的元素。 [ i .. end [中遗留的元素未指定,您有责任从容器中消除该间隔(如果需要):

auto i = std::remove(...);
v.erase(i,v.end());

你有一个额外的5的原因是典型的删除算法值复制到被删除的值留下的空洞中,因为超过i迭代器的值永远不会被覆盖后,它们与原始序列保持一致。但是,这种行为并不可靠 - 只需删除i之后的值而不读取它们。

答案 2 :(得分:2)

remove返回结尾。因此,代码的修复就是:

 std::vector<int> v = {1,2,3,4,5};
 auto newEnd = std::remove(v.begin(),v.end(),3);//return value stored in newEnd
 for(auto j = v.begin(); j!= newEnd ;++j) //note j!=newEnd
     std::cout << *j;

输出:

1245

亲自查看:http://www.ideone.com/3AMD9

答案 3 :(得分:-3)

您正在for()语句中打印向量的n + 1位置。 它应该是:

for(auto j = v.begin(); j!= v.end();j++)
   std::cout << *j;

j++++j