IntegralValue count(InputIterator first, InputIterator last, const EqualityComparable& value);
Produces the number of elements in [first, last) that are equivalent to value (when tested using operator==).
IntegralValue count_if(InputIterator first, InputIterator last, Predicate pred);
Produces the number of elements in [first, last) that each cause pred to return true.
Example
Here, a vector<char> v is filled with random characters (including some duplicates). A set<char> is initialized from v, so it holds only one of each letter represented in v. This set counts all the instances of all the characters, which are then displayed:.
//: C06:Counting.cpp
// The counting algorithms
#include <algorithm>
#include <functional>
#include <iterator>
#include <set>
#include <vector>
#include "Generators.h"
#include "PrintSequence.h"
using namespace std;
int main() {
vector<char> v;
generate_n(back_inserter(v), 50, CharGen());
print(v.begin(), v.end(), "v", "");
// Create a set of the characters in v:
set<char> cs(v.begin(), v.end());
typedef set<char>::iterator sci;
for(sci it = cs.begin(); it != cs.end(); it++) {
int n = count(v.begin(), v.end(), *it);
cout << *it << ": " << n << ", ";
}
int lc = count_if(v.begin(), v.end(),
bind2nd(greater<char>(), 'a'));
cout << "\nLowercase letters: " << lc << endl;
sort(v.begin(), v.end());
print(v.begin(), v.end(), "sorted", "");
} ///:~
The count_if( ) algorithm is demonstrated by counting all the lowercase letters; the predicate is created using the bind2nd( ) and greater function object templates.
Manipulating sequences
These algorithms let you move sequences around.
OutputIterator copy(InputIterator first, InputIterator last, OutputIterator destination);
Using assignment, copies from [first, last) to destination, incrementing destination after each assignment. This is essentially a "shuffle-left" operation, and so the source sequence must not contain the destination. Because assignment is used, you cannot directly insert elements into an empty container or at the end of a container, but instead you must wrap the destination iterator in an insert_iterator (typically by using back_inserter( ) or by using inserter( ) in the case of an associative container).
BidirectionalIterator2 copy_backward(BidirectionalIterator1 first, BidirectionalIterator1 last, BidirectionalIterator2 destinationEnd);
Like copy( ), but actually copies the elements in reverse order. This is essentially a "shuffle-right" operation, and, like copy( ), the source sequence must not contain the destination. The source range [first, last) is copied to the destination, but the first destination element is destinationEnd - 1. This iterator is then decremented after each assignment. The space in the destination range must already exist (to allow assignment), and the destination range cannot be within the source range.
void reverse(BidirectionalIterator first, BidirectionalIterator last); OutputIterator reverse_copy(BidirectionalIterator first, BidirectionalIterator last, OutputIterator destination);
Both forms of this function reverse the range [first, last). reverse( ) reverses the range in place, and reverse_copy( ) leaves the original range alone and copies the reversed elements into destination, returning the past-the-end iterator of the resulting range.
ForwardIterator2 swap_ranges(ForwardIterator1 first1, ForwardIterator1 last1, ForwardIterator2 first2);
Exchanges the contents of two ranges of equal size by swapping corresponding elements.
void rotate(ForwardIterator first, ForwardIterator middle, ForwardIterator last); OutputIterator rotate_copy(ForwardIterator first, ForwardIterator middle, ForwardIterator last, OutputIterator destination);
Moves the contents of [first, middle) to the end of the sequence, and the contents of [middle, last) to the beginning. With rotate( ), the swap is performed in place; and with rotate_copy( ) the original range is untouched, and the rotated version is copied into destination, returning the past-the-end iterator of the resulting range. Note that while swap_ranges( ) requires that the two ranges be exactly the same size, the "rotate" functions do not.
bool next_permutation(BidirectionalIterator first, BidirectionalIterator last); bool next_permutation(BidirectionalIterator first, BidirectionalIterator last, StrictWeakOrdering binary_pred); bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last); bool prev_permutation(BidirectionalIterator first, BidirectionalIterator last, StrictWeakOrdering binary_pred);
A permutation is one unique ordering of a set of elements. If you have n unique elements, there are n! (n factorial) distinct possible combinations of those elements. All these combinations can be conceptually sorted into a sequence using a lexicographical (dictionary-like) ordering and thus produce a concept of a "next" and "previous" permutation. Therefore, whatever the current ordering of elements in the range, there is a distinct "next" and "previous" permutation in the sequence of permutations.
The next_permutation( ) and prev_permutation( ) functions rearrange the elements into their next or previous permutation and if successful return true. If there are no more "next" permutations, the elements are in sorted order; so next_permutation( ) returns false. If there are no more "previous" permutations, the elements are in descending sorted order; so previous_permutation( ) returns false.
The versions of the functions that have a StrictWeakOrdering argument perform the comparisons using binary_pred instead of operator<.
void random_shuffle(RandomAccessIterator first, RandomAccessIterator last); void random_shuffle(RandomAccessIterator first, RandomAccessIterator last RandomNumberGenerator& rand);