关于不同容器拷贝
1 利用for循环
如果要拷贝不同容器类型的时候我们要使用迭代器来进行容器内范围拷贝
#include <iostream>
#include <vector>
#include <list>
using namespace std;
int main()
{
list<int> l = { 1, 2, 3 };
vector<int> v(3 , -1);
for (auto iter =l.begin();iter != l.end();iter++)
{
v.push_back(*iter);
}
for (auto iter = v.begin(); iter != v.end(); iter++)
{
cout << *iter << " ";
}
return 0;
}
2 memcpy(不能用于不同容器间拷贝)
#include<stdio.h>
#include<string.h>
int main()
{
char str[] = "*****";
char aim[] = "I study hard";
memcpy(aim, str, 5);
printf("复制之后的结果:%s", aim);
return 0;
}
3 std::copy、std::copy_if
std::copy 就是一个专门用于容器间拷贝的函数,其效率是优于使用for循环的!但是需要注意的是:std::copy 只负责复制,不负责申请空间,所以复制前必须有足够的空间
#include <iostream>
#include <numeric>//std::iota
#include <vector>
#include <algorithm>
int main()
{
//iota 可用于生成连续的数字序列
std::vector<int> fromVector(10);
std::iota(fromVector.begin(), fromVector.end(), 0);
//
std::vector<int> toVector;
std::copy(fromVector.begin(), fromVector.end(), std::back_inserter(toVector));
#if 0
// 或者
std::vector<int> toVector(fromVector.size());
std::copy(fromVector.begin(), fromVector.end(), toVector.begin());
// 无论哪种方式,实际结果都相当于
std::vector<int> toVector = fromVector;
#endif
//利用copy 进行输出
std::cout << "toVector contains: ";
std::copy(toVector.begin(), toVector.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
//把toVector中偶数拷贝到
//匿名函数
std::cout << "even numbers in toVector are: ";
std::copy_if(toVector.begin(), toVector.end(),
std::ostream_iterator<int>(std::cout, " "),
[](int x) { return std::fmod(x, 2) == 0; });
std::cout << '\n';
//把fromVector中是3的倍数拷贝到toVector
std::cout << "toVector contains these multiples of 3:\n";
toVector.clear();
std::copy_if(fromVector.begin(), fromVector.end(),
std::back_inserter(toVector),
[](int x) { return std::fmod(x, 3) == 0; });
for (int x : toVector)
std::cout << x << ' ';
std::cout << '\n';
return 0;
}
运行截图
安插型迭代器(insert iterators)
安插型迭代器可以使算法以安插(insert)方向而非覆写(overwrite)方式运作。使用它可以解决目标空间不足问题。也就是说,安插型迭代器会促使目标区间的大小按需要增长。安插型迭代器内部将接口重新做了定义:如果你对容器中的某个数据元素设值(assign),会引发“对其所属的容器内的数据元素的安插(insert)操作”至于插入的位置是在容器的最前还是最后,或是特定的位置,它根据三种不同的安插型迭代器(insert iterators)而定。
1)back_inserter(container):使用push_back()在容器尾端安插元素,元素排列顺序和安插顺序相同。只有在提供了push_back()成员函数的容器才能使back_inserter(container)这样的容器有:vector,deque,list
2)front_inserter(container):在内部调用push_front()成员函数,将元素安插于容器中最前端。采用头插法插入元素,数据元素在容器中的位置和插入时的顺序刚好相反。同样,只有提供了push_front()成员函数的容器才能使用 front_inserter(container)这样的迭代器有:deque,list.
3)inserter(container,pos):在内部调用insert()成员函数,将元素插入第二个参数所指的位置。因为在stl所有的容器中都包含有insert()成员函数,所以所有的容器包括关联式容器都能够使用 inserter(container, pos).但是,我们知道关联式容器中数据元素是有序的,数据元素在容器中的位置只是和元素值有关。在关联式容器中,提供一个迭代器只是告诉容器确定从什么地方开始搜寻正确的位置,如果提示不正确的话,效率比没有提示更糟,所以对关联式容器来说,我们必须慎重 。
#include <iostream>
#include <numeric>//std::iota
#include <vector>
#include <algorithm>
#include<list>
void fun(int a) {
std::cout << a << " ";
}
int main()
{
//iota 可用于生成连续的数字序列
std::vector<int> fromVector(10);
std::iota(fromVector.begin(), fromVector.end(), 0);
//copy第三个参数底层调用的是push_back
std::vector<int> toVector;
std::copy(fromVector.begin(), fromVector.end(), std::back_inserter(toVector));
#if 0
// 或者
std::vector<int> toVector(fromVector.size());
std::copy(fromVector.begin(), fromVector.end(), toVector.begin());
// 无论哪种方式,实际结果都相当于
std::vector<int> toVector = fromVector;
#endif
//利用copy 进行输出
std::cout << "toVector contains: ";
std::copy(toVector.begin(), toVector.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << '\n';
//把toVector中偶数拷贝到
//匿名函数
std::cout << "even numbers in toVector are: ";
std::copy_if(toVector.begin(), toVector.end(),
std::ostream_iterator<int>(std::cout, " "),
[](int x) { return std::fmod(x, 2) == 0; });
std::cout << '\n';
//把fromVector中是3的倍数拷贝到toVector
std::cout << "toVector contains these multiples of 3:\n";
toVector.clear();
std::copy_if(fromVector.begin(), fromVector.end(),
std::back_inserter(toVector),
[](int x) { return std::fmod(x, 3) == 0; });
for (int x : toVector)
std::cout << x << ' ';
std::cout << '\n';
//适用容器:vector,deque,list
std::cout << "back_inserter从后面正序插入:" << std::endl;
std::list<int> vct1 = { 1,2,3,4,5,6 };
std::list<int> vct2 = { -1,-1 };
copy(vct1.begin(), vct1.end(), std::back_inserter(vct2));
for_each(vct2.begin(), vct2.end(), fun);
std::cout << std::endl;
//适用容器:deque,list
std::cout << "front_inserter从前面逆序插入:"<<std::endl;
std::list<int> vct3 = { -1,-1 };
copy(vct1.begin(), vct1.end(), std::front_inserter(vct3));
for_each(vct3.begin(), vct3.end(), fun);
std::cout << std::endl;
//适用所有容器,但不建议在关联性容器使用
std::cout << "inserter从前面(可自定义位置,依据自定义迭代器)正序插入:" << std::endl;
std::list<int> vct4 = { -1,-1 };
copy(vct1.begin(), vct1.end(), std::inserter(vct4,vct4.begin()));
for_each(vct4.begin(), vct4.end(), fun);
return 0;
}
运行截图
注意:
copy搭配上面三种迭代器使用可以实现在不同容器间拷贝,但是要注意三种迭代器的适用容器,即函数参数要是对应的适用容器对象