我得到一个文件作为输入,我读这样的第一行(引号标记开始和结束,但不在文件中):
" 1, 2.0, 3.0, 4.0 "
Run Code Online (Sandbox Code Playgroud)
当我像这样使用remove命令时:
astring = line;
cout << endl << "Before trim: " << line << endl;
remove(astring.begin(), astring.end(), ' ');
cout << endl << "After trim: " << astring << endl;
Run Code Online (Sandbox Code Playgroud)
我得到的输出为:
1,2.0,3.0,4.02.0, 3.0, 4.0
Run Code Online (Sandbox Code Playgroud)
我只需要输出1,2.0,3.0,4.0.这里有什么问题?
是否可以访问std :: for_each迭代器,因此我可以使用lambda从std :: list中删除当前元素(如下所示)
typedef std::shared_ptr<IEvent> EventPtr;
std::list<EventPtr> EventQueue;
EventType evt;
...
std::for_each(
EventQueue.begin(), EventQueue.end(),
[&]( EventPtr pEvent )
{
if( pEvent->EventType() == evt.EventType() )
EventQueue.erase( ???Iterator??? );
}
);
Run Code Online (Sandbox Code Playgroud)
我读过关于使用[](typename T :: value_type x){delete x; 这里是SO,但是VS2010似乎不喜欢这个语句(将T作为错误源加下划线).
从STL中的集合中删除项目需要使用经常使用的技术,这已成为一种成语:擦除 - 删除 - 成语
这个成语最常见的用法之一是T从a中删除一个类型的项目vector<T>
std::vector<Widget> widget_collection;
Widget widget;
widget_collection.erase(
std::remove(widget_collection.begin(), widget_collection.end(), widget),
widget_collection.end());
Run Code Online (Sandbox Code Playgroud)
这显然非常冗长,违反了DRY原则 - 有问题的载体需要4次.
所以我的问题是为什么标准不提供方便助手?
就像是
widget_collection.erase_remove(widget);
Run Code Online (Sandbox Code Playgroud)
要么
std::erase_remove(widget_collection, widget);
Run Code Online (Sandbox Code Playgroud)
这显然可以扩展到
widget_collection.erase_remove_if(widget, pred);
Run Code Online (Sandbox Code Playgroud)
等等...
当我erase-remove idiom从Scott Meyers的"Effective STL"一书中读到(第32项)时,我得到了这个问题.
vector<int> v;
...
v.erase(remove(v.begin(), v.end(), 99), v.end());
Run Code Online (Sandbox Code Playgroud)
remove 基本上返回"新逻辑结束"和原始范围的元素,从元素的"新逻辑结束"开始并继续,直到范围的实际结束是要从容器中删除的元素.
听起来不错.现在,让我问一下我的问题:
在上面的例子中,如果没有找到99就remove可以返回.它基本上是通过擦除方法.v.end()vector vpast-the-end-iterator
past-the-end-iterator传递给erase方法时会发生什么?标准是否说它是UB?erase-remove idiomScott Meyer的书中的示例应该看起来像: vector<int> v;
...
vector<int>::iterator newEndIter = remove(v.begin(), v.end(), 99);
if(newEndIter != v.end() )
{
v.erase(newEndIter, v.end();
}
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
对于xC++列表中每次运行或连续的零,我想删除运行中的所有零,除了x它们.如果x = 0,则删除全部为零.
我在考虑一个C++函数,它将一个列表list<int> L和一个数字int x作为输入.
例如,让我们L = {7, 0, 12, 0, 0, 2, 0, 0, 0, 27, 10, 0, 0, 0, 0, 8}.
x = 0,那么回来L = {7, 12, 2, 27, 10, 8}x = 1,那么回来L = {7, 0, 12, 0, 2, 0, 27, 10, 0, 8}x = 2,那么回来L = {7, 0, 12, 0, 0, 2, 0, …#include <iostream>
#include <vector>
#include <algorithm>
int main()
{
enum class En{A, B};
std::vector<En> vec{En::A, En::B, En::A, En::B, En::A, En::B, En::A};
for(const auto& i : vec) std::cout << int(i) << ", ";
std::cout << std::endl;
vec.erase(std::remove(std::begin(vec), std::end(vec), vec.front()),
std::end(vec));
for(const auto& i : vec) std::cout << int(i) << ", ";
std::cout << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Ideone:http://ideone.com/NTPVyE
打印:
0,1,0,1,0,1,0,
1,0,0,0,
为什么会这样?不应该只删除矢量的第一个元素吗?
我想std::remove不会停留在第一个元素,而是贯穿整个向量.有没有什么方法可以使用非独特元素的集合上的擦除删除习惯用法?
std :: remove_if是否总是按顺序调用每个元素的谓词(根据迭代器的顺序),还是可以不按顺序调用?
这是我想做的玩具示例:
void processVector(std::vector<int> values)
{
values.erase(std::remove_if(values.begin(), values.end(), [](int v)
{
if (v % 2 == 0)
{
std::cout << v << "\n";
return true;
}
return false;
}));
}
Run Code Online (Sandbox Code Playgroud)
我需要处理和删除满足特定条件的向量的所有元素,并且erase + remove_if似乎是完美的.但是,我将要做的处理有副作用,我需要确保按顺序处理(在玩具示例中,假设我想按照它们在原始矢量中出现的顺序打印值).
假设我的谓词将按顺序调用每个项目是否安全?
我假设C++ 17的执行策略会消除歧义,但由于C++ 17还没有出来,这显然对我没有帮助.
编辑:另外,这是个好主意吗?或者有更好的方法来实现这一目标吗?
我需要从满足某个标准的向量中擦除所有元素.
我的第一种方法是遍历向量并在符合条件的所有元素上调用vector :: erase.
据我所知,vector::erase这个用例的性能不好,因为它从底层数组中删除了项目,并将向量的其余部分向前移动了一个元素(如果擦除了一系列元素,则移动更多).当您移除多个元素时,后部元素将在每次移除时移动.
该remove算法将所有元素移除,并将它们移动到向量的末尾,因此您只需要移除向量的后部,这不涉及移位.
但为什么这比擦除更快?(它更快吗?)
不将元素移动到最后是否意味着将所有后续元素向前移动vector::erase?
怎么来,删除只有O(n)的复杂性?
我无法正确掌握这个想法和程序(我是初学者):我有一个向量.Vector让我们说元素:fieldA,fieldB,fieldC.因此,有了这些向量的数组,我想检查,从数组中的最后一个向量开始,并转到第一个向量的方向,如果其中一个元素具有特定值,则让我们说if(vect [i]. fieldA == 0.0).在这种情况下,如果(vect [i-1] .fieldA == 0.0)具有相同的值,我想从数组中删除整个向量.有人能为我提供一部分可视化的代码,如何创建正确的"反向迭代"循环并使用函数删除它?我尝试使用erase(),remove(),deque()但是我失败了.
我不想在这里弄乱我的代码.
感谢帮助!
我想切割数组,不仅删除向量的内容!在classB和classA之间有适当的继承,所以喂养效果很好,我只想通过删除向量来解决这个问题.示例:2个元素的向量数组.输入:0,1 0,3 3,3 2,3 0,6 5,6 0,8 0,7 0,6输出:0,1 0,3 3,3 2,3 0,6 5,6 0 8.结论:移除了0,7和0,6个载体.
classA tmp;
for (std::vector<std::classB>::iterator iter = newW.begin(); iter != newW.end(); iter++)
{
tmp.set_fieldA(iter->a);
tmp.set_fieldB(iter->b);
tmp.set_fieldC(iter->c);
objA.push_back(tmp);
}
vector<std::classA> objA;
for(int i = objA.size()-1; i > 0; i--)
{
if (objA[i].fieldA == 0.0)
if (objA[i-1].fieldA == 0.0)
objA.erase(objA[i-1]); //remove last vector from array
}
Run Code Online (Sandbox Code Playgroud) 我不清楚是否unordered_map允许在做某事时进行重组erase()
很明显,在insert()使所有迭代器和引用无效的过程中可能会发生重新散列:
http://en.cppreference.com/w/cpp/container/unordered_map/insert
但erase()似乎保留所有迭代器和引用,除了擦除的那些:
http://en.cppreference.com/w/cpp/container/unordered_map/erase
但是,最后一页和标准表明erase()最差的执行时间是O(size).什么操作可以花费线性时间来完成而不是以使迭代器无效的方式修改容器?
这篇文章表明在删除过程中迭代器无效:http: //kera.name/articles/2011/06/iterator-invalidation-rules-c0x/
我还读到某个地方,未来的提案将允许重新开始erase().真的吗?
如果确实发生了重复,那么旧的迭代和擦除算法是错的吗?