Сначала функция equal_range
lower_bound
и upper_bound
, чтобы объединить их возвращаемые значения в пару и затем вернуть эту пару вызывающей стороне.Для получения функции бинарного поиска, которая просто возвращает первый элемент, соответствующий требованиям, мы могли бы реализовать следующее:
template
Iterator standard_binary_search(Iterator it, Iterator end_it, T value)
{
const auto potential_match (lower_bound(it, end_it, value));
if (potential_match != end_it && value == *potential_match) {
return potential_match;
}
return end_it;
}
Эта функция использует вызов std::lower_bound
value
. Полученный результат potential_match
может соответствовать одному из трех сценариев.□ Ни один элемент не соответствует нашему условию. В таком случае значение potential_match
end_it
.□ Первый найденный элемент, соответствующий условию,
end_it
.□ Элемент, на который указывает potential_match
Если наш тип T
==
, то должен поддерживать хотя бы оператор <
для выполнения бинарного поиска. Далее можно переписать сравнение как !(value < *potential_match) && !(*potential_match < value)
. Если найденный элемент не меньше и не больше искомого, то он должен быть равен искомому.Одной из потенциальных причин, по которой STL не предоставляет такую функцию, является отсутствие информации о том, что делать, если обнаружено несколько совпадений, как было показано на рис. 5.1, где вектор содержит несколько значений 7
std::map
std::set
и т.д. имеют собственные функции find
. Они работают быстрее, чем более обобщенные алгоритмы, поскольку тесно связаны с реализациями структур данных.Ограничиваем допустимые значения вектора конкретным численным диапазоном с помощью std::clamp
Во многих приложениях мы получаем из некоторого источника численные данные. Прежде чем у нас получится построить для них график или обработать их как-то иначе, может понадобиться нормализовать их, поскольку значения, сгенерированные случайным образом, чаще всего заметно отличаются друг от друга.
Обычно это значит, что нужно выполнить вызов std::transform
Библиотека STL содержит полезные функции, которые можно применить для решения данной задачи: std::minmax_element
std::clamp
. Эти функции можно использовать в совокупности с некоторыми лямбда-выражениями.Как это делается
В этом примере мы нормализуем значения вектора из примера диапазона чисел двумя способами, использовав методы std::minmax_element
std::clamp
.1. Как и всегда, сначала включим следующие заголовочные файлы и объявим об использовании пространства имен std
#include
#include
#include
#include
using namespace std;
2. Реализуем функцию, принимающую минимальное и максимальное значения диапазона, а также новый максимум, что позволит проецировать значения из старого диапазона в более мелкий. Объект функции принимает подобные значения и возвращает другой объект функции, который выполняет именно такое преобразование. Для простоты этим значением будет 0
max
и min
могут быть одинаковыми, что приведет к делению на ноль.static auto norm (int min, int max, int new_max)
{
const double diff (max - min);
return [=] (int val) {
return int((val - min) / diff * new_max);
};
}