r******9 发帖数: 129 | 1 用iterator遍历一个vector
然后当某个元素符合某种条件时,删掉这个元素
我一直想这么干
vector ::iterator iter = vec.begin();
while(iter != vec.end())
{
if(test(iter->content) == true)
{
vec.erase(iter);
}
++iter;
}
但是这样肯定不行,好像不能再循环体内改变vector
我现在的解决办法就是吧要删的元素的index记下来,然后再对这个index做循环,逐个
删。
高手们有没有好的办法啊?
谢谢啦 |
r*******m 发帖数: 109 | 2 v.erase( remove_if(v.begin(), v.end(), test), v.end() );
【在 r******9 的大作中提到】 : 用iterator遍历一个vector : 然后当某个元素符合某种条件时,删掉这个元素 : 我一直想这么干 : vector ::iterator iter = vec.begin(); : while(iter != vec.end()) : { : if(test(iter->content) == true) : { : vec.erase(iter); : }
|
r******9 发帖数: 129 | |
X****r 发帖数: 3557 | 4 remove_if
【在 r******9 的大作中提到】 : 用iterator遍历一个vector : 然后当某个元素符合某种条件时,删掉这个元素 : 我一直想这么干 : vector ::iterator iter = vec.begin(); : while(iter != vec.end()) : { : if(test(iter->content) == true) : { : vec.erase(iter); : }
|
f******y 发帖数: 2971 | 5 Better to use list.
【在 r******9 的大作中提到】 : 用iterator遍历一个vector : 然后当某个元素符合某种条件时,删掉这个元素 : 我一直想这么干 : vector ::iterator iter = vec.begin(); : while(iter != vec.end()) : { : if(test(iter->content) == true) : { : vec.erase(iter); : }
|
i**h 发帖数: 424 | 6 Or,
if(test(iter->content)==true)
{
iter = vec.erase(iter)
}
else
{
++iter;
} |
t****t 发帖数: 6806 | 7 if you want to erase every element this will be O(n^2) for vector. not good.
【在 i**h 的大作中提到】 : Or, : if(test(iter->content)==true) : { : iter = vec.erase(iter) : } : else : { : ++iter; : }
|
v*s 发帖数: 946 | 8 看了STL的文档才明白,原来这个remove_if其实没有真正删除东西,只是把所有不满足
test的元素挪到容器的尾部,并返回指向他们第一个的指针。 然后外面的erase才把那
些不满足条件的元素全部干掉。
牛!
【在 r*******m 的大作中提到】 : v.erase( remove_if(v.begin(), v.end(), test), v.end() );
|
t*****t 发帖数: 52 | 9 用list是一个方法,还有一个方法是用另外一个vector, 符合条件的不管,不符合的
push_back到另一个, 最后交换两个vector的指针, OK. |
t****t 发帖数: 6806 | 10 and the benefit of this method is?
【在 t*****t 的大作中提到】 : 用list是一个方法,还有一个方法是用另外一个vector, 符合条件的不管,不符合的 : push_back到另一个, 最后交换两个vector的指针, OK.
|
|
|
g*********s 发帖数: 1782 | 11 why not move them to the begin?
【在 v*s 的大作中提到】 : 看了STL的文档才明白,原来这个remove_if其实没有真正删除东西,只是把所有不满足 : test的元素挪到容器的尾部,并返回指向他们第一个的指针。 然后外面的erase才把那 : 些不满足条件的元素全部干掉。 : 牛!
|
h********m 发帖数: 386 | 12 If (... ==true)
Vec.erase(tier++)
else
Iter++
Iter++ does two things before erase happen. Increment iter and return
original iter pos
So u will be fine
【在 r******9 的大作中提到】 : 用iterator遍历一个vector : 然后当某个元素符合某种条件时,删掉这个元素 : 我一直想这么干 : vector ::iterator iter = vec.begin(); : while(iter != vec.end()) : { : if(test(iter->content) == true) : { : vec.erase(iter); : }
|
g*********s 发帖数: 1782 | 13 but vector must keep the continuous storage semantics.
【在 h********m 的大作中提到】 : If (... ==true) : Vec.erase(tier++) : else : Iter++ : Iter++ does two things before erase happen. Increment iter and return : original iter pos : So u will be fine
|
v*s 发帖数: 946 | 14 这个问题你得去问stl的发明人,俺不清楚。
【在 g*********s 的大作中提到】 : why not move them to the begin?
|
S**I 发帖数: 15689 | 15 this will cause run-time error almost for sure; erase a vector iterator
invalidates all iterator to elements after the erased iterator.
【在 h********m 的大作中提到】 : If (... ==true) : Vec.erase(tier++) : else : Iter++ : Iter++ does two things before erase happen. Increment iter and return : original iter pos : So u will be fine
|
g*********s 发帖数: 1782 | 16 haha, i misread ur post. it's elements being removed put to end, not being
kept, never mind.
【在 v*s 的大作中提到】 : 这个问题你得去问stl的发明人,俺不清楚。
|
S**I 发帖数: 15689 | 17 strictly speaking, this is not right, either. remove (and remove_if) only
moves "unremoved" elements to the beginning, there is no guarantee that what
's left at the end are "removed" elements.
【在 g*********s 的大作中提到】 : haha, i misread ur post. it's elements being removed put to end, not being : kept, never mind.
|
a*****i 发帖数: 268 | |
s****m 发帖数: 160 | 19 这是C++ STL的一个idiom, 但是实在是counter-intuitive,
只能死记。
【在 r*******m 的大作中提到】 : v.erase( remove_if(v.begin(), v.end(), test), v.end() );
|
X****r 发帖数: 3557 | 20 这有什么counter-intuitive的?如果自己手工做的话,
还不是维持两个iterator,把所有需要保留的移到前面?
remove_if只是帮你写了这个而已。
C++虽然繁复,要死记的部分其实也不多。
【在 s****m 的大作中提到】 : 这是C++ STL的一个idiom, 但是实在是counter-intuitive, : 只能死记。
|
|
|
t****t 发帖数: 6806 | 21 for encapsulated containers (or other objects), people intend to "use" the
exposed methods, e.g. vector::erase(). if it is an array and there is no
erase() method, most likely they won't simulate it.
humans are lazy. if a human want to go through a wall, and someone give him
a pick, he will probably dig through the wall. but if there is no pick, he
probably will take the easy way -- walk around it. haha.
【在 X****r 的大作中提到】 : 这有什么counter-intuitive的?如果自己手工做的话, : 还不是维持两个iterator,把所有需要保留的移到前面? : remove_if只是帮你写了这个而已。 : C++虽然繁复,要死记的部分其实也不多。
|
r********3 发帖数: 2998 | 22 如果在Java里面,我都是重新创建一个新的vector。在Java里面,删除一个元素总是要
移动后面,效率还不如重新创建一个新的vector,然后销毁原来整个vector。
【在 r******9 的大作中提到】 : 用iterator遍历一个vector : 然后当某个元素符合某种条件时,删掉这个元素 : 我一直想这么干 : vector ::iterator iter = vec.begin(); : while(iter != vec.end()) : { : if(test(iter->content) == true) : { : vec.erase(iter); : }
|
f******y 发帖数: 2971 | 23 Java is Java.
【在 r********3 的大作中提到】 : 如果在Java里面,我都是重新创建一个新的vector。在Java里面,删除一个元素总是要 : 移动后面,效率还不如重新创建一个新的vector,然后销毁原来整个vector。
|
r*******m 发帖数: 109 | 24 It's more efficient for vector since remove one by one will move things
around. Remove_if does not change the size of the vector. But I agree it's
not intuitive.
Funny it was once asked during an interview.
【在 s****m 的大作中提到】 : 这是C++ STL的一个idiom, 但是实在是counter-intuitive, : 只能死记。
|
d*********8 发帖数: 2192 | 25 需要在VECTOR中间删除元素,你首先要问自己为啥用的是VECTOR. |
r********3 发帖数: 2998 | 26 还有个办法,你的intro to algorithm里面的洗牌算法嘛?
如果我要删除中间的元素,我就先把这个元素和最后一个元素交换,然后删除最后一个
元素,这样就不用移动了。
当然,这样要是无序的vector才行。
【在 r*******m 的大作中提到】 : It's more efficient for vector since remove one by one will move things : around. Remove_if does not change the size of the vector. But I agree it's : not intuitive. : Funny it was once asked during an interview.
|
t*****t 发帖数: 52 | 27 if processing order is not important, why use vector. the set and
unordered_set is much simpler in semantics, and, most important, easily
parallelized.
【在 r********3 的大作中提到】 : 还有个办法,你的intro to algorithm里面的洗牌算法嘛? : 如果我要删除中间的元素,我就先把这个元素和最后一个元素交换,然后删除最后一个 : 元素,这样就不用移动了。 : 当然,这样要是无序的vector才行。
|
r********3 发帖数: 2998 | 28 因为vector随机访问速度很快,基本就是1,2条指令。set的话,即便是hashset所谓O(1
)也是几十条指令。至于TreeSet这些都是Log(N)的复杂度了。
另外最重要的一点,vector里面的内存是连续分配的。在分配和回收上,分散的set是
无法比拟的。
【在 t*****t 的大作中提到】 : if processing order is not important, why use vector. the set and : unordered_set is much simpler in semantics, and, most important, easily : parallelized.
|