Функция insert_sorted
std::set
, std::deque
, std::list
и т.д.! (Обратите внимание: контейнер set
имеет собственную функцию-член lower_bound
, которая делает то же самое, что и функция std::lower_bound
, но более эффективно, поскольку создана специально для множеств.)template
void insert_sorted(C &v, const T &item)
{
const auto insert_pos (lower_bound(begin(v), end(v), item));
v.insert(insert_pos, item);
}
При попытке изменить тип контейнера, приведенный в примере, с std::vector
std::sort
. Этот алгоритм предполагает использование контейнеров с произвольным доступом. Таковым, например, не является контейнер std::list
. Вставляем элементы в контейнер std::map эффективно и в соответствии с условиями
Иногда нужно заполнить ассоциативный массив парами «ключ — значение», и при выполнении данной задачи можно столкнуться с двумя ситуациями.
1. Заданный ключ не существует. В этом случае создается
2. Заданный ключ уже существует. В такой ситуации берем
Конечно, мы могли бы просто воспользоваться методами insert
emplace
контейнера map
и проверить успешность их выполнения. Или же нужно модифицировать существующий элемент. В обоих вышеперечисленных случаях функции insert
и emplace
создают элемент, который мы пытаемся вставить, а во втором случае только что созданный элемент отбрасывается. В обоих случаях совершается бесполезный вызов конструктора.Начиная с С++17, в STL появилась функция try_emplace
try_emplace
.Как это делается
В этом примере мы реализуем приложение, которое создает ассоциативный массив на основе списка миллиардеров. В нем отображаются названия стран и ссылки на самого богатого человека, проживающего в данной стране, а также счетчик, указывающий количество миллиардеров.
1. Как всегда, включим некоторые заголовочные файлы; объявим также об использовании пространства имен std
#include
#include
#include
#include
using namespace std;
2. Определим структуру, которая представляет миллиардеров из нашего списка:
struct billionaire {
string name;
double dollars;
string country;
};
3. В функции main
int main()
{
list
{"Bill Gates", 86.0, "USA"},
{"Warren Buffet", 75.6, "USA"},
{"Jeff Bezos", 72.8, "USA"},
{"Amancio Ortega", 71.3, "Spain"},
{"Mark Zuckerberg", 56.0, "USA"},
{"Carlos Slim", 54.5, "Mexico"},
// ...
{"Bernard Arnault", 41.5, "France"},
// ...
{"Liliane Bettencourt", 39.5, "France"},
// ...
{"Wang Jianlin", 31.3, "China"},
{"Li Ka-shing", 31.2, "Hong Kong"}
// ...
};
4. Теперь определим ассоциативный массив. В нем строка, содержащая страну, соотносится с парой. Пара включает неизменяемую копию первого миллиардера из каждой страны из нашего списка. Эти люди являются самыми богатыми жителями своей страны. Другая переменная, входящая в пару, — счетчик, который будет увеличиваться на каждого последующего миллиардера в стране:
map
5. Теперь пройдем по списку и попробуем для каждой страны заменить соответствующее значение новой парой. Пара включает ссылку на миллиардера, которого мы просматриваем в данный момент, и значение счетчика, равное 1