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给出的答案看起来是正确的
答案 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
惯用法实际删除元素,即erase
与remove
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
答案 3 :(得分:-3)
您正在for()
语句中打印向量的n + 1位置。
它应该是:
for(auto j = v.begin(); j!= v.end();j++)
std::cout << *j;
j++
否++j