Algorithm

The algorithm header file contains template functions that operate on ranges of elements. Range is defined as [first, last) where last refers to the element past the last element to inspect or modify.

namespace utils

Functions

template<typename Iterator>
std::size_t argmax(Iterator first, Iterator last)

Finds the index of the maximum element in a range.

Template Parameters:

Iterator – Type of the input iterator.

Parameters:
  • first – Iterator to the beginning of the range.

  • last – Iterator to the end of the range.

Returns:

The index of the maximum element in the range.

template<typename InputIt1, typename InputIt2, typename UnaryPred>
InputIt1 max_element_conditional(InputIt1, InputIt1, InputIt2, UnaryPred p)

Finds the maximum element in a range that satisfies a given predicate.

Template Parameters:
  • InputIt1 – Type of the first input iterator.

  • InputIt2 – Type of the second input iterator.

  • UnaryPred – Type of the unary predicate.

Parameters:
  • first1 – Iterator to the beginning of the first range.

  • last1 – Iterator to the end of the first range.

  • first2 – Iterator to the beginning of the second range.

  • p – Unary predicate that returns true for the elements to be considered.

Returns:

Iterator to the maximum element in the first range that satisfies the predicate.

template<typename InputIt1, typename InputIt2, typename UnaryPred>
std::pair<bool, std::size_t> argmax_conditional(InputIt1 first1, InputIt1 last1, InputIt2 first2, UnaryPred p)

Finds the index of the maximum element in a range that satisfies a given predicate.

Template Parameters:
  • InputIt1 – Type of the first input iterator.

  • InputIt2 – Type of the second input iterator.

  • UnaryPred – Type of the unary predicate.

Parameters:
  • first1 – Iterator to the beginning of the first range.

  • last1 – Iterator to the end of the first range.

  • first2 – Iterator to the beginning of the second range.

  • p – Unary predicate that returns true for the elements to be considered.

Returns:

A pair where the first element is a boolean indicating if a valid maximum element was found, and the second element is the index of the maximum element in the first range that satisfies the predicate.

template<typename InputIt, typename OutputIt>
OutputIt copy_range_n_times(InputIt first, InputIt last, OutputIt d_first, std::size_t n)

Copies a range of elements multiple times to a destination.

This function copies the elements in the range [first, last) to the destination range starting at d_first, n times. The destination range must be large enough to hold n copies of the input range.

Note

If n is less than 0, the behavior is undefined.

Template Parameters:
  • InputIt – Input iterator type for the source range.

  • OutputIt – Output iterator type for the destination range.

Parameters:
  • first – The beginning of the source range.

  • last – The end of the source range.

  • d_first – The beginning of the destination range.

  • n – The number of times to copy the source range.

Returns:

OutputIt Iterator to the end of the last copied range.

template<typename BidirIt1, typename BidirIt2>
std::pair<BidirIt1, BidirIt2> mismatch_from_end(BidirIt1 first1, BidirIt1 last1, BidirIt2 last2)

Finds the first position where two ranges differ, starting from the end.

Template Parameters:
  • BidirIt1 – Bidirectional iterator type for the first range.

  • BidirIt2 – Bidirectional iterator type for the second range.

Parameters:
  • first1, last1 – The range of the first sequence.

  • last2 – The end of the second sequence.

Returns:

A pair of iterators to the first mismatching elements from the end.

template<typename RandomIt1, typename RandomIt2>
void reorder_elements_by_indices(RandomIt1 first1, RandomIt1 last1, RandomIt2 indices_first)

Reorders elements in a range based on given indices.

This function reorders the elements in the range [first1, last1) according to the indices provided in the range starting at indices_first2. The indices specify the new positions of the elements.

Remark

Range [indices_first2, std::next(indices_first2, std::distance(first1, last1))) is modified.

Note

It is assumed that the indices are valid and within the range [0, std::distance(first1, last1)).

Template Parameters:
  • RandomIt1 – Type of the random access iterator for the elements.

  • RandomIt2 – Type of the random access iterator for the indices.

Parameters:
  • first1 – Iterator to the beginning of the elements range.

  • last1 – Iterator to the end of the elements range.

  • indices_first – Iterator to the beginning of the indices range.

Usage

The following examples demonstrates how to use the algorithm header file:

  • argmax

const std::vector v{1, 3, 5, 7, 9};
const auto result{utils::argmax(v.begin(), v.end())};
std::cout << "result: " << result << std::endl;

Output:

result: 4
  • argmax_conditional

const std::vector v1{1, 3, 5, 7, 9};
const std::vector v2{0, 1, 0, 1, 0};
const auto result{utils::argmax_conditional(v1.begin(), v1.end(), v2.begin(), [](const int x) { return x == 1; })};
std::cout << std::boolalpha
          << "result.first: " << result.first
          << ", result.second: " << result.second std::endl;

Output:

result.first: true, result.second: 3
  • copy_range_n_times

const std::vector source{1, 2, 3};
std::vector<int> destination(9);
const auto result{utils::copy_range_n_times(source.begin(), source.end(), destination.begin(), 3)};
std::cout << desination: ";
for (const auto& elem : result) {
    std::cout << elem << " ";
}

Output:

destination: 1 2 3 1 2 3 1 2 3
  • max_element_conditional

const std::vector v1{1, 3, 5, 7, 9};
const std::vector v2{0, 1, 0, 1, 0};
const auto result{
        utils::max_element_conditional(v1.begin(), v1.end(), v2.begin(), [](const int x) { return x == 1; })};
std::cout << "result: " << result << std::endl;

Output:

result: 7
  • mismatch_from_end

const std::vector vec1{3, 4, 5};
const std::vector vec2{1, 2, 3, 4, 5};
const auto &[mis_first, mis_second] = utils::mismatch_from_end(vec1.begin(), vec1.end(), vec2.end());
std::cout << "*mis_first: " << *mis_first
          << ", *mis_second: " << *mis_second << std::endl;

Output:

*mis_first: 3, *mis_second: 3
  • reorder_elements_by_indices

std::vector elements{10, 20, 30, 40};
std::vector indices{3, 2, 1, 0};
utils::reorder_elements_by_indices(elements.begin(), elements.end(), indices.begin());
std::cout << "elements: ";
for (const auto& e : elements) {
    std::cout << e << " ";
}

Output:

elements: 40 30 20 10