C++ <vector> функция insert

класс контейнера C++ <vector>


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&lt;class InputIt&gt;
void insert(iterator pos, InputIt first, InputIt last);

// 初始化列表方式插入
void insert(iterator pos, std::initializer_list&lt;T&gt; ilist);

Описание параметра

  • Параметр: pos
    • Тип: iterator (iterator)
    • Описание: итератор позиции вставки. Новый элемент будет вставленposперед.
    • Параметр: value
      • Тип: такой же, как тип элемента контейнера
      • Описание: значение элемента для вставки.
      • Параметр: n
        • Тип:size_type
        • Описание: количество элементов для вставки.

      Описание функции

      • Возвращаемое значение: возвращает итератор, указывающий на первый вставленный элемент (для вставки одного элемента).
      • Действие: вставляет элемент в указанную позицию, сдвигая последующие элементы назад по порядку.
      • Примечание: insertМожет вызвать перераспределение памяти, и все существующие итераторы могут стать недействительными.

      Пример

      Давайте тщательно освоим это на серии примеров.insertИспользование.

      Пример 1: Базовое использование — вставка одного элемента.

      Пример

      #include <iostream>
      #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
      

      Анализ кода:

      1. numbers.begin() + 1Указывает на позицию второго элемента.
      2. insertВставить 100 перед этой позицией.
      3. Последующие элементы сдвигаются назад на одну позицию.

      Пример 2: Вставка элементов в начало

      Использованиеbegin()Можно вставлять элементы в начало контейнера.

      Пример

      #include <iostream>
      #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 <iostream>
      #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 <iostream>
      #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 <iostream>
      #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 <iostream>
      #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Добавляет элемент в конец.

      класс контейнера C++ <vector>

      Другие расширения