C++ <vector> функция insert
insertиспользуется в vector длявставки элементов в указанную позициюявляется наиболее гибким методом вставки в контейнерах.
insertявляется функцией-членом класса-контейнера, используемой длявставки одного или нескольких элементов в указанную позицию в контейнере.Она принимает позицию итератора и элемент для вставки.
insertпредоставляет возможность вставлять элементы в любую позицию. Хотя в vector эффективность не так хороша, какpush_back(требует перемещения последующих элементов), зато он более мощный.
Определения слов: insertозначает "insert", то есть добавление элемента в указанную позицию.
Базовый синтаксис и параметры
insertявляется функцией-членом класса-контейнера, требующей указания позиции вставки и элемента.
Формат синтаксиса
// 在 pos 位置插入 value 的副本 iterator insert(iterator pos, const T& value); // 在 pos 位置插入 value 的副本(移动) iterator insert(iterator pos, T&& value); // 在 pos 位置插入 n 个 value 的副本 void insert(iterator pos, size_type n, const T& value); // 在 pos 位置插入 [first, last) 范围内的元素 template<class InputIt> void insert(iterator pos, InputIt first, InputIt last); // 初始化列表方式插入 void insert(iterator pos, std::initializer_list<T> ilist);
Описание параметра
- Параметр:
pos- Тип: iterator (
iterator) - Описание: итератор позиции вставки. Новый элемент будет вставлен
posперед.
- Тип: iterator (
- Параметр:
value- Тип: такой же, как тип элемента контейнера
- Описание: значение элемента для вставки.
- Параметр:
n- Тип:
size_type - Описание: количество элементов для вставки.
- Тип:
- Возвращаемое значение: возвращает итератор, указывающий на первый вставленный элемент (для вставки одного элемента).
- Действие: вставляет элемент в указанную позицию, сдвигая последующие элементы назад по порядку.
- Примечание:
insertМожет вызвать перераспределение памяти, и все существующие итераторы могут стать недействительными.
Описание функции
Пример
Давайте тщательно освоим это на серии примеров.insertИспользование.
Пример 1: Базовое использование — вставка одного элемента.
Пример
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
std::cout << "Исходный вектор: ";
for(int n : numbers) std::cout << n << " ";
std::cout << std::endl;
// Вставить 100 во вторую позицию (индекс 1)
auto it = numbers.begin() + 1;
numbers.insert(it, 100);
std::cout << "После вставки 100: ";
for(int n : numbers) std::cout << n << " ";
std::cout << std::endl;
return 0;
}
Ожидаемый вывод:
原始 vector: 1 2 3 4 5 插入 100 后: 1 100 2 3 4 5
Анализ кода:
numbers.begin() + 1Указывает на позицию второго элемента.insertВставить 100 перед этой позицией.- Последующие элементы сдвигаются назад на одну позицию.
Пример 2: Вставка элементов в начало
Использованиеbegin()Можно вставлять элементы в начало контейнера.
Пример
#include <vector>
#include <string>
int main() {
std::vector<std::string> names = {"Bob", "Charlie"};
std::cout << "Исходный: ";
for(const auto& n : names) std::cout << n << " ";
std::cout << std::endl;
// Вставить в начало
names.insert(names.begin(), "Alice");
std::cout << "Вставка Alice в начало: ";
for(const auto& n : names) std::cout << n << " ";
std::cout << std::endl;
return 0;
}
Ожидаемый вывод:
原始: Bob Charlie 在开头插入 Alice: Alice Bob Charlie
Анализ кода:
names.begin()Указывает на первый элемент.- Вставьте в эту позицию, и новый элемент станет первым элементом.
Пример 3: Вставка нескольких одинаковых элементов
Можно вставить несколько одинаковых элементов в указанную позицию.
Пример
#include <vector>
int main() {
std::vector<int> numbers = {1, 5};
std::cout << "Исходный: ";
for(int n : numbers) std::cout << n << " ";
std::endl;
// Вставить 3 нуля в середину
auto it = numbers.begin() + 1;
numbers.insert(it, 3, 0);
std::cout << После вставки 3 нулей:;
for(int n : numbers) std::cout << n << " ";
std::cout << std::endl;
return 0;
}
Ожидаемый вывод:
原始: 1 5 插入 3 个 0 后: 1 0 0 0 5
Анализ кода:
insert(it, 3, 0)Вставить 3 элемента со значением 0 перед позицией it.
Пример 4: Вставка элементов из другого вектора.
Можно вставить несколько элементов из другого контейнера.
Пример
#include <vector>
int main() {
std::vector<int> v1 = {1, 2, 3};
std::vector<int> v2 = {10, 20, 30};
std::cout << "v1: ";
for(int n : v1) std::cout << n << " ";
std::cout << std::endl;
std::cout << "v2: ";
for(int n : v2) std::cout << n << " ";
std::cout << std::endl;
// Вставить все элементы v2 во вторую позицию v1
v1.insert(v1.begin() + 1, v2.begin(), v2.end());
std::cout << После вставки, v1:;
for(int n : v1) std::cout << n << " ";
std::cout << std::endl;
return 0;
}
Ожидаемый вывод:
v1: 1 2 3 v2: 10 20 30 插入后 v1: 1 10 20 30 2 3
Анализ кода:
v1.insert(v1.begin() + 1, v2.begin(), v2.end())Вставить все элементы v2 перед второй позицией v1.
Пример 5: Вставка с использованием списка инициализации
C++11 поддерживает вставку элементов с использованием списка инициализации.
Пример
#include <vector>
int main() {
std::vector<int> numbers = {1, 5};
std::cout << "Исходный: ";
for(int n : numbers) std::cout << n << " ";
std::cout << std::endl;
// Вставка с использованием списка инициализации
numbers.insert(numbers.begin() + 1, {2, 3, 4});
std::cout << После вставки:;
for(int n : numbers) std::cout << n << " ";
std::cout << std::endl;
return 0;
}
Ожидаемый вывод:
原始: 1 5 插入后: 1 2 3 4 5
Анализ кода:
- Использование
initializer_listМожно вставить несколько элементов сразу.
Пример 6: Проблемы эффективности insert.
Используется в вектореinsertВставка элементов в начало или в середину менее эффективна.
Пример
#include <vector>
#include <chrono>
int main() {
const int N = 10000;
// Вставка в начало (неэффективно)
std::vector<int> v1;
auto start1 = std::chrono::high_resolution_clock::now();
for(int i = 0; i < N; ++i) {
v1.insert(v1.begin(), i);
}
auto end1 = std::chrono::high_resolution_clock::now();
auto duration1 = std::chrono::duration_cast<std::chrono::microseconds>(end1 - start1);
// Вставка в конец (эффективно)
std::vector<int> v2;
v2.reserve(N);
auto start2 = std::chrono::high_resolution_clock::now();
for(int i = 0; i < N; ++i) {
v2.push_back(i);
}
auto end2 = std::chrono::high_resolution_clock::now();
auto duration2 = std::chrono::duration_cast<std::chrono::microseconds>(end2 - start2);
std::cout << Вставка в начало << N << элементов заняла: << duration1.count() << " microseconds" << std::endl;
std::cout << Вставка в конец << N << элементов заняла: << duration2.count() << " microseconds" << std::endl;
return 0;
}
Анализ кода:
- Вставка элемента в начало вектора требует перемещения всех существующих элементов, что очень неэффективно.
- Если вам нужно часто вставлять в начало, рассмотрите использование
dequeилиlist。 - Предпочтительно использовать
push_backДобавляет элемент в конец.
Другие расширения