Algorithms
Base Code and C++ version
For the sake of testing this code, we'll specify a very basic C++ file that our code would run in. Note that we include vector
, because that's the container the examples will use, we're including iostream
for cout
, and we including algorithm
for the actual STL algorithms.
main.cpp
We'll use a simple makefile to compile and run, specifying C++11.
makefile
And so to actually run this code, in a UNIX operating system, in the terminal, simply type make
in the directory where your makefile and main.cpp are.
Figure Something Out About Data
Need to do something with the data in your container? Look here.
all_of
Check if every element in the range satisfies the condition.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and a lambda function that does something with the element of the container.
Returns a bool. True if all elements satisfied the condition, false otherwise.
any_of
Check if any element in the range satisfies the condition.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and a lambda function that does something with the element of the container.
Returns a bool. True if any element satisfied the condition, false otherwise.
none_of
Check if none of the elements in the range satisfies the condition.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and a lambda function that does something with the element of the container.
Returns a bool. True if all elements fail the condition, false if any element passes the condition.
for_each
Does something for each item in a range.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and a lambda function that does something with the element of the container.
Returns void.
find
Find an item in a given range.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and an item that you want to find.
Returns an iterator to the first element in the range that is equal to the item we specified.
find_if
Find the first item that satisfies a condition.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and a lambda function that returns a bool.
Returns an iterator to the first element in the range that satisfies the lambda's condition.
find_if_not
Find the first item that does not satisfy a condition.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and a lambda function that returns a bool.
Returns an iterator to the first element in the range that does not satisfy the lambda's condition.
find_end
For a range, find the last occurence of a sequence in that range. (Ex. Get the last "oo" in "moo_cookies".)
Pass in an iterator to the beginning of the first range, and an iterator to the end of the first range, and an iterator to the beginning of the sequence, and an iterator to the end of the sequence,
Returns an iterator to the first item of the sequence.
find_first_of
For a range, find the first occurence of a sequence in that range. (Ex. Get the first "oo" in "moo_cookies".)
Pass in an iterator to the beginning of the first range, and an iterator to the end of the first range, and an iterator to the beginning of the sequence, and an iterator to the end of the sequence,
Returns an iterator to the first item of the sequence.
adjacent_find
Find the first occurrence of two consecutive elements that match in a range. (Ex. The "cc" in "accent".)
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns an iterator to the first item in the match.
count
Count the number of times an item appears in the range.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and the item we want to count.
Returns an integer.
count_if
Count the number of occurrences satisfying the lambda function.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and a lambda function that returns true or false.
Returns an integer.
mismatch
Finds the first occurrence where two rangers differ.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and an iterator to the beginning of the second range.
Returns a
pair
of iterators to the positions where the ranges occur.
equal
Check if the elements in two ranges are equal.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and an iterator to the beginning of the second range.
Returns a bool. True if the elements are equal, false otherwise.
is_permutation
Check if a range is a permutation of another.
A "permutation" is if the items in one range can be rearranged to form the other range. (Ex. "dog" can be rearranged to form "god".)
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and an iterator to the beginning of the second range.
Returns a bool. True if the elements are permutations, false otherwise.
search
Check if a range contains a certain sequence. (Ex. Does "this" contain "is"?)
Pass in an iterator to the beginning of the first range, and an iterator to the end of the first range, and an iterator to the beginning of the second range (sequence), and an iterator to the end of the second range (sequence).
Returns an iterator to the first item in the range that begins the sequence.
search_n
Search a range for a certain number of a specific item. (Ex. Find two 'e's in a row in the word 'esteem'.)
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and the count of the number of the item we need to find, and the item we're trying to find.
Returns an iterator to the first item in the range that begins the sequence.
lexicographical_compare
Lexographically compare two items to find out which is 'smaller'.
Pass in an iterator to the beginning of the first range, and an iterator to the end of the first range, an iterator to the beginning of the second range, and an iterator to the end of the second range.
Returns a bool. True if the first range is lexographically less than the second range.
Modify/Copy A Range
A range is going to be edited or copied.
copy
Copy the elements from one range into another.
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, and an iterator to the beginning of the copy range.
Returns an iterator to the element after the last one we wrote to in the copy range.
copy_n
Copy the first n elements from one range into another.
Pass in an iterator to the beginning of the first range, an int representing how many elements to copy, and an iterator to the beginning of the copy range.
Returns an iterator to the element after the last one we wrote to in the copy range.
copy_if
Copy elements from one range into another if the condition we specify is met.
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, an iterator to the beginning of the copy range, and a lambda function that returns a bool.
Returns an iterator to the element after the last one we wrote to in the copy range.
copy_backward
Copy the elements from one range into another, starting from the back elements and going to the front.
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, and an iterator to the end of the copy range.
Returns an iterator to the last element we wrote to in the copy range (which is the beginning of the copy range).
move
Move the elements from one range into another. The elements in the original range are valid, but may not be what they were before the move.
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, and an iterator to the beginning of the move range.
Returns an iterator to the element after the last one we wrote to in the move range.
move_backward
Move the elements from one range into another, starting from the back elements and going to the front. The elements in the original range are valid, but may not be what they were before the move.
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, and an iterator to the end of the move range.
Returns an iterator to the last element we wrote to in the move range (which is the beginning of the move range).
swap
Swaps the values of two items.
Pass in the first and the second item.
Returns void.
swap_ranges
Given two ranges, swaps the items in them (using the swap
function).
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, and an iterator to the beginning of the second range.
Returns an iterator to the element after the last one we wrote to in the second range.
iter_swap
Swap the values that two iterators point too.
Pass in an iterator to the first value, and an iterator to the second value.
Returns void.
transform
Given one or two ranges, performs an operation on each value of the range and stores that result in another range. (For example, multiply each value in a vector by some number and store it in another vector. Or add each value in two vectors and put that into another vector.)
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, (optionally, an iterator to the beginning of the second range if there is one), and an iterator to the beginning of the resulting range, and a lamba expression that accepts the element type(s) and returns the element type that does the operation we want to want to do on the range(s).
Returns an iterator to the element after the last one we wrote to in the resulting range.
Example with just one range:
Example with two ranges:
replace
For a range, replaces an old value (that we specify) with a new value (that we specify). (Ex. Replace all 3's with 7's.)
Pass in an iterator to the beginning of the range, an iterator to the end of the range, the old value, and the new value.
Returns void.
replace_if
For a range, replaces an element that passes a certain condition with a new value (that we specify). (Ex. Replace all negative elements with a 0.)
Pass in an iterator to the beginning of the range, an iterator to the end of the range, a lambda expression that returns a bool, and the new value.
Returns void.
replace_copy
For a range, copies the elements into another range, and replaces any element (that we specify) with a new value (that we specify) for the new range. Doesn't change the old range. (Ex. Replace all 3's with 7's.)
Pass in an iterator to the beginning of the range, an iterator to the end of the range, an iterator to the beginning of the new range, the old value, and the new value.
Returns an iterator to the element after the last one we wrote to in the resulting range.
replace_copy_if
For a range, copies the elements into another range, and replaces any element that passes a certain condition with a different value (that we specify) for the new range. Doesn't change the old range. (Ex. Replace all negative elements with a 0.)
Pass in an iterator to the beginning of the range, an iterator to the end of the range, an iterator to the beginning of the new range, a lambda expression that returns a bool, and the new value.
Returns an iterator to the element after the last one we wrote to in the resulting range.
fill
For a range, fill every element with an item (that we specify). (Ex. Fill a range with all 7s.)
Pass in an iterator to the beginning of the range, an iterator to the end of the range, and the value that we want to fill it with.
Returns void.
fill_n
For a range, fill every element with an item (that we specify). (Ex. Fill the first 3 elements of a range with 7s.)
Pass in an iterator to the beginning of the range,the number of elements we want to fill, and the value that we want to fill it with.
Returns an iterator to the element after the last one we wrote to.
generate
For a range, assigns each element with a value generated by a function (that we specify). (Ex. Use a random number generator function to determine what to assign each element.)
Pass in an iterator to the beginning of the range, an iterator to the end of the range, and a function (that accepts no parameters) that returns the type of the range.
Returns void.
generate_n
For a range, assigns each element with a value generated by a function (that we specify) for the first n elements. (Ex. Use a random number generator function to determine what to assign each element for the first 3 elements.)
Pass in an iterator to the beginning of the range, the number of elements we want assign to, and a function (that accepts no parameters) that returns the type of the range.
Returns an iterator to the element after the last one we wrote to.
remove
For a range, removes any element that has a certain value (that you specify). This is done by moving a valid element into the removed element's spot. (The container size does not change.) You'll know where the updated range ends by checking where the returned iterator is. Order is not preserved, and the extra elements at the end of the range are in some valid state.
Pass in an iterator to the beginning of the range, an iterator to the end of the range, and the value to be removed.
Returns an iterator after the last valid element in the range.
remove_if
For a range, removes any element that passes a certain condition (that you specify). This is done by moving a valid element into the removed element's spot. (The container size does not change.) You'll know where the updated range ends by checking where the returned iterator is. Order is not preserved, and the extra elements at the end of the range are in some valid state.
Pass in an iterator to the beginning of the range, an iterator to the end of the range, and a lambda function that returns a bool.
Returns an iterator after the last valid element in the range.
remove_copy
For a given range, copies each element into a new range, except for elements with a certain value (that you specify). The original range is untouched.
Pass in an iterator to the beginning of the original range, an iterator to the end of the original range, an iterator to the beginning of the copy range, and the value that you want to skip.
Returns an iterator after the last valid element in the copy range.
remove_copy_if
For a given range, copies each element into a new range, except for elements that pass a certain condition (that you specify). The original range is untouched.
Pass in an iterator to the beginning of the original range, an iterator to the end of the original range, an iterator to the beginning of the copy range, and a lambda function that returns a bool.
Returns an iterator after the last valid element in the copy range.
unique
For a range, remove consecutive duplicate elements. (Ex. { 2 2 3 3 4 4 4 3 } -> { 2 3 4 3 ? ? ? ? } ) This is done by moving a valid element into the removed element's spot. (The container size does not change.) You'll know where the updated range ends by checking where the returned iterator is. Order is not preserved, and the extra elements at the end of the range are in some valid state.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns an iterator after the last valid element in the range.
unique_copy
For a range, copies all elements that don't have a duplicate neighbor into a new range (that you specify). (Ex. { 2 2 3 3 4 4 4 3 } -> { 2 3 4 3 } ) The original range is untouched.
Pass in an iterator to the beginning of the original range, an iterator to the end of the original range, and an iterator to the beginning of the copy range.
Returns an iterator after the last copied element in the copy range.
reverse
For a range, reverses the order of the elements. (Ex. { 1 2 3 4 } -> { 4 3 2 1 } .)
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns void.
reverse_copy
For a range, copies the elements in verse order into a new range (that you specify). (Ex. { 1 2 3 4 } -> { 4 3 2 1 } .) The original range is untouched.
Pass in an iterator to the beginning of the original range, an iterator to the end of the original range, and an iterator to the beginning of the copy range.
Returns an iterator after the last copied element in the copy range.
rotate
For a range, rotates the elements (in a circular fashion) so that a specified becomes the new first element, and every other element is shifted over.
Pass in an iterator to the beginning of the range, an iterator to the element we want to be the beginning of the range, and an iterator to the end of the range.
Returns void.
rotate_copy
For a range, copies the elements into a new range if the elements were rotating (in a circular fashion) so that a specified becomes the new first element, and every other element is shifted over. The original range is untouched.
Pass in an iterator to the beginning of the original range, an iterator to the element we want to be the beginning of the copy range. an iterator to the end of the original range, and an iterator to the beginning of the copy range.
Returns an iterator after the last copied element in the copy range.
random_shuffle
For a range, rearranges the elements randomly. (random_shuffle
uses rand()
as the random number generator.)
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns void.
shuffle
For a range, rearranges the elements randomly using a uniform random number generator (that you must provide).
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and a random number generator.
Returns void.
You should really be using random
or some other library to provide a random number generator. Since the code example isn't simple, I'll just provide a link to cplusplus.com's shuffle page for sample code..
Partitioned
Operate on partioned data, which is split in half based on a certain condition.
is_partitioned
Check if the data in a range is partitioned according to a condition you specify. (Ex. Are the odd elements separated from the even elements?)
Pass in an iterator to the beginning of the range, an iterator to the end of the range, and a lambda that returns a bool.
Returns a bool. True if the data is in the beginning all return true and the data afterward all return false. Returns false otherwise.
Note that if the data is all false and then all true, is_partitioned
will return false. Make sure your lambda will return "true" for the front data. For example..
isPartitioned is false even though the data is clearly partitioned. That's because the first partition returns false and the second partition returns true.
partition
Rearranges the elements in a range so that the first group returns true for the condition you specify. (Ex. Move all odd elements to the front.)
Pass in an iterator to the beginning of the range, an iterator to the end of the range, and a lambda that returns a bool.
Returns an iterator to the first element of the second partition.
stable_partition
Rearranges the elements in a range so that the first group returns true for the condition you specify. (Ex. Move all odd elements to the front.) Order is preserved.
Pass in an iterator to the beginning of the range, an iterator to the end of the range, and a lambda that returns a bool.
Returns an iterator to the first element of the second partition.
partition_copy
For a range, copies the data which is true for a condition we specify into some range, and copies the data that is false into some other range.
Pass in an iterator to the beginning of the original range, an iterator to the end of the original range, an iterator to the beginning of the "true" range, an iterator to the end of the "false" range, and a lambda that returns a bool.
Returns a
pair
of iterators to the element after the last entered element for each of the copy ranges.
partition_point
Get the first element in a partitioned range that returns false for a given condition. (The element that begins the partition.)
Pass in an iterator to the beginning of the range, an iterator to the end of the range, and a lambda that returns a bool.
Returns an iterator to the element.
Sorting
Sorting data.
sort
Sort the elements in a container for the given range.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns void.
stable_sort
Sort the elements in a container for the given range, but the sort is stable.
A "stable" sort means that for equal elements, an element that was ahead of another before the sort will be ahead after the sort.
Stable sort is best used for objects.
partial_sort
For a position in a range, make sure all the elements from the beginning of the range up to that position are the smallest elements in the range and are sorted. (The rest of the elements (which are up to the position until the end of the range) aren't in any specific order.)
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and an iterator to the position we want to partially sort for.
Returns void.
In the code example, v ends up fully sorted, but only the first three elements are guaranteed to be sorted.
partial_sort_copy
Copies the items from a range into a second range, in sorted order.
Pass in an iterator to the beginning of the first range, and an iterator to the end of the first range, and an iterator to the beginning of the range we want to copy into, and an iterator to the end of the range we want to copy into,
Returns an iterator to the item after where we finished writing to in the copy range.
is_sorted
Check whether a given range is sorted.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns a bool. True if the range is sorted, false if it's not sorted.
is_sort_until
Finds the first element in a range that isn't sorted.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns an iterator to the first unsorted element.
nth_element
For the position that you specify in a range, places the element at that position that would be there if the range was sorted. ("What would the nth element be if this range was sorted" without actually sorting the entire range.)
Pass in an iterator to the beginning of the range, an iterator to the position we want to find out about, and an iterator to the end of the range.
Returns void. (The range is edited, though.)
Binary Search
These algorithms are about binary searching O(log N) a sorted range for a value.
lower_bound
Returns an iterator for the lower bound of an element in a range.
"Lower bound" means the first element that is not less than the element we're searching for.
For example, for vector [3, 3, 4, 4, 4, 5, 7], lower_bound(4) points to the very first 4 (at index 2). lower_bound(6) points to 7, since that's the first element not less than 6.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and the element you want to search for.
Returns an iterator to the element. (Or to the container's end if the element doesn't exist.)
upper_bound
Returns an iterator for the upper bound of an element in a range.
"Upper bound" means the first element that is greater than the element we're searching for.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and the element you want to search for.
Returns an iterator to the element. (Or to the container's end if the element doesn't exist.)
equal_range
Finds the starting index and ending index for an element in a range. (Meaning if we have duplicates of an item in a container, and we want to find out the range of where those items are.)
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and the element you want to search for.
Returns an
pair
of iterators of the element type.
binary_search
Returns true if an element exists in a sorted range. Returns false otherwise. Does a binary search to find the item.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range, and the element you want to search for.
Returns a bool.
Sorted Data Operations
Is your data sorted? If yes, then do these efficient operations on them.
merge
Given two sorted ranges, combine them to form one larger sorted range.
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, an iterator to the beginning of the second range, an iterator to the end of the second range, and an iterator to the beginning of the resulting range that you want to place all of the data into.
Returns an iterator to the end of the resulting range after placing the last item into it.
inplace_merge
Given two consecutive sorted ranges (in the same container), do an in-place merge to sort the entire range.
Pass in an iterator to the beginning of the first sorted range, an iterator to the beginning of the second sorted range, and an iterator to the end of the second sorted range.
Returns void.
includes
Check if a given a sorted range contains a second (sorted) range (that you specify). (Ex. Does "abcmopxyz" contain "mop"?)
Pass in an iterator to the beginning of the first sorted range, an iterator to the end of the first sorted range. an iterator to the beginning of the second sorted range, and an iterator to the second sorted range.
Returns a bool. True if the first range contains the second range, false if it doesn't.
set_union
Given two sorted ranges, creates a new sorted range from the elements that exist in either range. (The union.)
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, an iterator to the beginning of the second range, an iterator to the end of the second range, and an iterator to the beginning of the resulting range that you want to place all of the data into.
Returns an iterator to the element after the last element we placed in the resulting range.
Notice that there are only two 1's in the resulting range. set_union
will take the maximum number of an element from one range; it won't just add them.
set_intersection
Given two sorted ranges, created a new sorted range from the elements that exist in both ranges. (The intersection.)
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, an iterator to the beginning of the second range, an iterator to the end of the second range, and an iterator to the beginning of the resulting range that you want to place all of the data into.
Returns an iterator to the element after the last element we placed in the resulting range.
set_difference
Given two sorted ranges, created a new sorted range from the elements that exist in the first range that don't exist in the second range. (The difference.)
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, an iterator to the beginning of the second range, an iterator to the end of the second range, and an iterator to the beginning of the resulting range that you want to place all of the data into.
Returns an iterator to the element after the last element we placed in the resulting range.
set_symmetric_difference
Given two sorted ranges, created a new sorted range from the elements that exist in one of the ranges but doesn't exist in the other range. (The symmetric difference.)
Pass in an iterator to the beginning of the first range, an iterator to the end of the first range, an iterator to the beginning of the second range, an iterator to the end of the second range, and an iterator to the beginning of the resulting range that you want to place all of the data into.
Returns an iterator to the element after the last element we placed in the resulting range.
Notice the 1 in res. That's there because v2 has an extra 1 that v1 does not have.
Heap
Algorithms regarding heap data structures.
A "heap" is a binary tree that always has maximum element as the root node (top of the tree). It's used in priority queues. (It can also have the min element as the root.)
make_heap
Rearranges the items in a range so that they form a heap.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns void.
push_heap
If the first elements of a range are a heap, but the last item isn't, then push_heap
will place that last item into it's correct position.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns void.
pop_heap
Given a range for a heap, places the max element at the end of the range, and rearranges the rest of the elements to be a heap again.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns void.
sort_heap
If a range is a heap, rearrange it into sorted order.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns void.
is_heap
Check if a range is a heap.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns a bool. True if the range is a heap, false if it's not a heap.
is_heap_until
Find the first place in a range that makes the range fail being a heap.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns an iterator to the first element that makes the range fail being a heap.
Min and Max
These algorithms are related to finding the minimum/maximum element in a range, or when comparing two items.
min
Compares two items and returns the smaller one.
Pass in two items (
int
s, for example) as parameters.Returns the item's type.
max
Compares two items and returns the larger one.
Pass in two items (
int
s, for example) as parameters.Returns the item's type.
minmax
Kind of useless in my opinion. Not even going to post the implementation. see minmax_element
for something useful.
min_element
Returns an iterator to the smallest element for a given range.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns an iterator of the type of the collection.
max_element
Returns an iterator to the largest element for a given range.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns an iterator of the type of the collection.
minmax_element
Returns a pair
of iterators to the smallest and the largest elements for a given range. (The smallest is the first item, and the largest is the second item.)
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns an
std::pair
of iterators of type of the collection.
Permutations
Permute data into it's next transformation.
next_permutation
Rearranges the items in the specified range into the next lexographically greater permutation.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns a bool. True if the range was transformed, false otherwise (if there was no such possible permutation).
prev_permutation
Rearranges the items in the specified range into the previous lexographically ordered permutation.
Pass in an iterator to the beginning of the range, and an iterator to the end of the range.
Returns a bool. True if the range was transformed, false otherwise (if there was no such possible permutation).
Notes
The
auto
keyword was purposely not used often in this documentation, but use it in your real code.Note that I say "range" a lot, even though I specifically use
vector.begin()
andvector.end()
most of the time. Remember that your range can be anywhere in the container you want.Some algorithms also have an overloaded version to provide a custom comparator (for example,
stable_sort
), but I've ommitted those to keep the examples short.Pay careful attention to the ordering of the parameters, some are not intuitive. (Ex.
nth_element
)
Last updated