2. Algorithms #

Created Sun May 12, 2024 at 7:35 PM

find is a function (not method) that can be used on any container. BUT, we’ll avoid giving this too much precedence since most container have a method named find (method, not function), that’s much faster. Less confusion.

vector<int> v;
auto it = find(v.begin(), v.end(), 20);

Reference: https://cplusplus.com/reference/algorithm/#:~:text=range (function template)-,binary search,-(operating%20on%20partitioned

Existence #

binary_search(startIt, endIt, key); // existence check
// e.g 10 10 10 20 20 20 30 30
// key=20 => true
// key=21 => false

Lower bound (left side = || >) #

// Lower bound means "left side" (<=)
lower_bound (startIt, endIt, key);
lower_bound(v.begin(), v.end(), 20); // v is a vector

// e.g 10 10 10 20 20 20 30 30, key=20
// Result  is ..., 10, ^20

Upper bound (right side >) #

// upper bound means "right side" (>)
upper_bound (startIt, endIt, key);
upper_bound(v.begin(), v.end(), 20); // v is a vector

// e.g 10 10 10 20 20 20 30 30, key=20
// Result  is ..., 20, ^30, ...

Range (range from left to right side) #

Get “equivalent” range.

// left side >=, right side >
equal_range(startIt, endIt, key);

// e.g 10 10 10 20 20 20 30 30, key=20
// range is [20, 20, 20, 30]

Min and max #

Get value #

2-valued function.

min(a, b);
	min(a, b, customFunctor);
	int x = min(1, 2);
	
max (/* same as above */)
auto xPair = minmax (/* same as above */)

Get location #

min_element(startIt, endIt);
	min_element(startIt, endIt, customFunctor);
	
max_element (/* same as above */)
auto itPair = minmax_element (/* same as above */)

Sorting #

Reference: https://cplusplus.com/reference/algorithm/#:~:text=point (function template)-,sorting All are in-place ops.

sort (non stable) #

std::sort works for any container (except strict ADTs like stack, queue, or already sorted ones)

sort(startI, endI) // natural sort, i.e. increasing order, alphabetical order
	sort(startI, endI, greater<int>()) // decreasing order. 
	// Remember: greater is a call here, min PriorityQueue declaration is not a call.
	
	sort(starI, endI, [] -> bool (auto a, auto b){ return is_should_keep; }); // custom

stable_sort #

stable_sort(startIt, endIt);
	stable_sort(startIt, endIt, greater<int>()); // decreasing order
	stable_sort(starI, endI, [] -> bool (auto a, auto b){ return is_should_keep; }); // custom

Check if sorted #

is_sorted(startIt, endIt);

vector<int> v;
bool isSorted = is_sorted(v.begin(), v.end());

Comparison #

Equality #

Compare two ranges.

equal(startIt1, endIt1, startIt2, endIt2);
	equal(startIt1, endIt1, startIt2, endIt2, customFunctor); // [](a, b){ return a==b; }

Alphabetic order #

lexicographic_compare(startIt1, endIt1, startIt2, endIt2);
	lexicographic_compare(startIt1, endIt1, startIt2, endIt2, compareFunctor); // TBD

All, any, none #

all_of (startIt, endIt, customFunctor);
any_of (startIt, endIt, customFunctor); // !all_of(!item)
none_of(startIt, endIt, customFunctor);

Higher-order functions #

Can work on any data structure (except strict ADT like stack).

Map #

// HOFs - need decltype, back_inserter
// // map - transform()
decltype(v) output (v.size());
tranform(v.begin(), v.end(), output.begin(), [](){ return 1; }); // new array
	tranform(v.begin(), v.end(), v.begin(), [](){ return 1; }); // in-place

Filter #

// // Filter - copy_if()
decltype(v) output;
copy_if(v.begin(), v.end(), back_inserter(output), [](){ return 1; }); // new array
	 // in-place - resize, distance
	auto it = copy_if(v.begin(), v.end(), v.begin(), [](){ return 1; });
	v.resize(distance(v.begin(), it));

Reduce #

// // Reduce - accumulate()
auto result = accumulate(v.begin(), v.end(), 0, [](auto accum, auto item){ return accum * item; });

Count #

count(v.begin(), v.end(), key); // uses operator ==

count_if(v.begin(), v.end(), customFunctor); // [](auto a){}

Sequence ops #

Reverse #

Its a function, no container level methods are present. In place operation.

void reverse(startIt, endIt);

vector<int> v;
reverse(v.begin(), v.end());

string s;
reverse(s.begin(), s.end());

Rotate #

Rotate by k to the left. (movement right to left). In place operation.

rotate(startIt, middleIt, endIt); // rotates such that middleIt, becomes the first element
	rotate(startIt, startIt + k, endIt); // intuitive, rotate k to left.
	rotate(startIt, endIt - k, endIt); // intuitive, rotate k to right.

vector<int> v;
auto newVecIt = rotate(v.begin(), v.begin()+2, v.end());

string s;
auto newStrIt = rotate(s.begin(), s.begin()+2, s.end());

Partition #

auto firstItemOfRightGroupIt
 = partition(v.begin(), v.end(), customFunctor); // [](auto a) { return isOnLeft; }
	partition(v.begin(), v.end(), [](auto i) { return i <= k; }); // parition w.r.t value k

	stable_partition()// works the same but keeps stability (same values stay in order)

Merge #

merge(startIt1, endIt1, startIt2, endIt2, writerIt);
	// for vector
	decltype(v1) output (v1.size() + v2.size(), 0);
	merge(v1.begin(), v1.end(), v2.begin(), v2.end(), output.begin());

Set operations #

General set operations - do not exist. ❌ STL has functions only for sorted sets. All 4 supported:

set_union(startIt1, endIt1, startIt2, endIt2, writerIt);
set_intersection (/* same as above */)
set_difference (/* same as above */)
set_symmetric_difference (/* same as above */)

Permutations #

In-place operation. O(n/2).

next_permutation(startIt, endIt);
	next_permutation(startIt, endIt, compareFunctor); // [](auto a, b) { return is_should_swap; }

previous_permutation(startIt, endIt);

TBD