Функция copy в C++: легко и понятно!
Всем привет! Часто приходиться вывести некоторое количество элементов или добавить ячейки из одного контейнера в другой. Часто для это используется цикл for, но есть средство лучше — метод copy().
Что такое функция copy
copy — это метод который имеет четыре области применения.
- Первая — это выводить элементы от
n
-го итератора доj
. - Вторая — это добавлять элементы из контейнера A в контейнер B.
- Третья — это копирование диапазона ячеек и вставка его позицию X.
Эту функция поддерживают контейнеры: vector list set map
Как создать метод copy
1 |
copy(<первый>, <последний>, <операции>); |
первый
ипоследний
— это диапазон ячеек к которым будут выполнятся операции.- В
операции
входит:
Вывод элементов
ostream_iterator — это итератор вывода. Он применяется для вывода элементов.
Для оперирования этим итератором нужно подключить библиотеку — iterator
. Не поддерживает контейнер — map.
1 |
ostream_iterator<тип данных>(cout, "текст"); |
После ostream_iterator
должен стоять <тип данных>
выводимых элементов. Например — <int>
.
Разработчики сделали возможность выводить между элементами какую-то информацию — (cout, "ваш текст")
. В ваш текст
мы можем писать все что угодно, однако обычно там ставят пробел — " "
.
Вот так например мы смогли вывести весь список:
1 2 3 4 5 6 7 |
list <string> ilist; ilist.push_back("мир!"); ilist.push_front("Привет "); copy(ilist.begin(), ilist.end(), ostream_iterator<int>(cout," ")); |
Вот какой будет результат выполнения этой программы:
Добавление элементов
inserter — специальный тип итератора вывода который добавляет элементы из контейнера A в контейнер B.
1 |
copy(<первый>,<последний>, inserter(<имя контейнера>, <итератор>)); |
После него не нужно указывать тип данных. Только понадобится в скобках написать, в какой контейнер и в какое его место будет идти добавление элементов.
1 2 3 4 5 6 7 |
map <string, int> map_first; map <string, int> map_second; map_first["code"]++; map_first["lessons"]++; copy(map_first.begin(), map_first.end(), inserter(map_second, map_second.begin())); |
back_inserter — добавляет значения в конец STL контейнера.Не работает если третий аргумент указывает на map. Но работает c вектором пар (vector < pair <string, int> >
).
1 2 3 4 |
map <string, int> map_first; vector < pair <string, int> > vec_pair; copy(map_first.begin(), map_first.end(), back_inserter(vec_pair)); // работает! |
front_inserter — добавляет элементы в начала контейнера.Не работает с map vector.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#include <iostream> #include <list> #include <set> #include <iterator> using namespace std; int main() { set <int> set_t; set_t.insert(10); set_t.insert(20); set_t.insert(30); list <int> digitals; copy(set_t.begin(), set_t.end(), front_inserter(digitals)); copy(digitals.begin(), digitals.end(), ostream_iterator<int>(cout, " ")); system("pause"); return 0; } |
Копирование элементов
Для вставки копируемых элементов в контейнер нужно третьим аргументом передавать — итератор. От него начнут изменяться ячейки на значения другого контейнера. Не работает для set map.
1 |
copy(ilist.begin(), ilist.end(), ivec.begin()); |
Мы вставляем ячейки от начала контейнера —
ivec
.
В примере ниже мы изменим только вторую ячейку вектора answer
, хотя у вектора v
три ячейки.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <iostream> #include <iterator> // для использования ostream_iterator #include <vector> using namespace std; int main() { setlocale(0, ""); vector <int> v; // создали два vector <int> answer; // вектора v.push_back(1); v.push_back(2); v.push_back(3); answer.push_back(0); answer.push_back(10); cout << "вектор answer до использования copy: "; copy(answer.begin(), answer.end(), ostream_iterator<int>(cout , " ")); cout << endl; vector <int> :: iterator it = answer.begin(); // сделали итератор it который it++; // указывает на начала answer copy(v.begin(), v.end(), it); // изменили значения cout << "вектор answer после оперирования методом copy: "; copy(answer.begin(), answer.end(), ostream_iterator<int>(cout , " ")); // вывели все // элементы system("pause"); return 0; } |
Результат программы после запуска:
На этом все! Надеемся эта информация была для вас полезна. Если вы что-то не поняли или заметили в статье опечатку можете написать в комментарии. Удачи!
Последняя программа у вас не рабочая, так как при компиляции будет ошибка «выход за пределы вектора».
Это и понятно, так как первый вектор у вас имеет 3 элемента, а второй — только 2. Вставка этих 3-х элементов в второй происходит со 2-ой позиции, и естественно будет сгенерина ошибка.
Вот мой код:
int main()
{
std::vector_v1;
std::vector_v2;
_v1.push_back(1);
_v1.push_back(2);
_v1.push_back(3);
_v2.push_back(4);
_v2.push_back(5);
_v2.push_back(6);
_v2.push_back(7);
std::copy(_v2.begin(), _v2.end(), std::ostream_iterator(std::cout, » «));
std::cout << '\n';
std::vector::iterator _iter = _v2.begin();
_iter++;
std::copy(_v1.begin(), _v1.end(), _iter);
std::copy(_v2.begin(), _v2.end(), std::ostream_iterator(std::cout, » «));
return 0;
}
Программа про которую вы говорите будет работать. Элементы будут копироваться пока не дойдет до конца одного из массивов. А программа не компилировалась, потому что после
ostream_iterator
не было типа данных —int
. Спасибо, что заметили!ОНА НЕ РАБОТАЕТ((((((((((
У меня все отлично работает, возможно у вас старая версия компилятора. Либо же старая версия C++.
В 1 программе изза пуш фронт будет не привет мир, а мир привет. Так же ostream_iterator должен в качестве шаблонного типа получить string.
Спасибо, исправил.
В примере кода с front_inserter самого front_inserter и нет! ))
Спасибо, исправили!