开发者

Difference between partition() and remove() functions in C++

开发者 https://www.devze.com 2023-01-12 11:30 出处:网络
What is the difference between the partition() and remove() functions in C++? The remove doesn\'t actually remove any e开发者_如何转开发lements of the containers but puts the \'removed\' elements at

What is the difference between the partition() and remove() functions in C++?

The remove doesn't actually remove any e开发者_如何转开发lements of the containers but puts the 'removed' elements at the beginning of the sequence of elements and partition does the same thing as well.


remove [...] puts the 'removed' elements at the beginning of the sequence

What? No. Both remove_if and partition put the "good" elements first. partition puts the "bad" elements after that, whereas remove_if does not specify what comes after it -- it might be the bad elements, but it might also be copies of any (either good or bad) elements.

For example, if you partition 1 2 3 4 5 on even, you might get 2 4 5 3 1 (note that each element occurs exactly once), whereas if you remove_if the odd elements, you might get 2 4 3 4 5 (note the duplicates).


remove_if doesn't put the removed elements anywhere; the elements after the new end will have their old values, so some of the removed elements might be missing, and some of the preserved elements might be duplicated. This is faster than partition, and can be done with forward iterators while partition requires bidirectional iterators.

Update: in C++0x, partition will only require forward iterators, but will be even slower if the iterators aren't bidirectional.


If I understood it right, remove does not actually swap any elements but simply moves elements for which the predicate (in case of remove_if) is false to the beginning of the sequence. If you have

a = [1,1,1,2,3]

and call remove(a.begin(),a.end(),1), you'll have

a = [2,3,1,2,3]

afterwards. remove returns an iterator to the third element in this case (if I remember correctly ...)

partition on the other hand retains all original elements of the sequence but changes their order such that elements for which the given predicate is true are placed in front of elements for which it isn't.

partition(a.begin(), a.end(), not_equal<int>(1)) yields

a = [2,3,1,1,1]


From The C++ Standard Library: A Tutorial and Reference

remove() - Removes elements with a given value, logically only by overwriting them with the following elements that were not removed. Do not change the number of elements in the ranges on which they operate. Instead, they return the position of the new "end" of the range

partition() - Changes the order of the elements so that elements that match a criterion are at the front

stable_partition() - Same as partition() but preserves the relative order of matching and nonmatching elements


partition - "groups" the elements of a container according to a certain predicate (e.g. odd and even numbers in a std::vector)

remove - removes a certain value from a container; indeed elements are moved to the end of the initial container, an iterator to the new end is returned and the "removed" elements are still accessible

EDIT:

remove - removes a certain value from a container; elements are NOT moved to the end of the initial container as stated above, an iterator to the new end is returned but iterators in the range [newEnd, last) are still dereferenceable hence accessible BUT the elements they point to are unspecified.

0

精彩评论

暂无评论...
验证码 换一张
取 消