赞
踩
// 括号
std::vector<int> a (5); //0,0,0,0,0
std::vector<int> b (5,1); //1,1,1,1,1
// 花括号
std::vector<int> c = {1,2,3,4,5,6};
std::vector<int> c {1,2,3,4,5,6}; // 和上面的写法等价
std::vector<int> foo (3,0);
std::vector<int> bar (5,0);
bar = foo; //Copies all the elements from foo into the bar.
vector的内存也是连续的,可以和数组切换。
std::vector<int> a;
for (int i = 0; i < 1000; ++i)
{
a.push_back(i);
std::cout << "size: " << a.size() << " capacity: " << a.capacity() << std::endl;
}
std::vector<int> a;
a.reserve(1000); // size: 0 capacity: 1000
扩充:
reserve 和 resize 的区别?
resize 会调用构造函数,而 reserve 仅仅是开辟内存空间。直观的表现就是 resize 会改变 vector size 的值(此时 capacity 也可能会改变),而 reserve 改变的是 capacity。
vector<int> a(100, 1};
vector<int> b;
b.resize(100); // 这里如果是 reserve 会出错
std::copy(a.begin(), a.begin() + step, b.begin());
// insert 在指定位置之前插入指定数量的值 // 插入的过程中可能会造成realloc,这时 it 失效 std::vector<int> a = {1,2,3,4,5,6}; a.reserve(10); // 注意这里开辟了capcity,插入不会 realloc, it 不会失效,仍然指向 begin 位置 std::vector<int>::iterator it = a.begin(); a.insert(it, 1); // a = {1,1,2,3,4,5,6} a.insert(it, 3, 2); // a = {2,2,2,1,1,2,3,4,5,6} 注意插入的位置 std::vector<int> b = {11, 20, 30}; std::vector<int>::iterator it1 = b.begin(); a.insert(it, it1, it1 + 2); // a = {11,20,1,1,2,2,2,2,3,4,5,6} // emplace c++11 auto it = a.emplace ( a.begin()+1, 100 ); // a = {11,100,20,1,1,2,2,2,2,3,4,5,6} a.emplace ( it, 200 ); // a = {11,200,100,20,1,1,2,2,2,2,3,4,5,6} a.emplace ( a.end(), 300 ); // a = {11,200,100,20,1,1,2,2,2,2,3,4,5,6,300} // a.emplace_back(300) a.push_back(7);
C++11 及之后应该优先考虑用 emplace 或者 emplace_back,因为原地构造后加入容器,效率更高。
// 下标 a[0] // at a.at(0) // 推荐使用,越界会抛异常 // iterator a.begin() a.rbegin() //reverse a.cbegin() //const a.crbegin() //特殊位置 a.front() a.back() // data int* p = myvector.data(); cout << *p;
// 批量修改
a.assign(5,1);
a.assign(b.begin(), b.begin()+5)
a.swap(b) //交换 a, b 的data
// 单个修改。。。
a.erase(b.begin()) //删除单个,这里需要注意的是 erase 返回的是删除位置的下一个位置的迭代器
a.erase(b.begin(), b.begin()+5) //删除多个
a.clear();//删除所有
利用 algorithm 提供的 sort 进行排序。
sort(vector.begin(), vector.end()); // 从小到大排序
sort(a.begin(), a.end(), [](int x, int y) {return x > y; }); // 从大到小排序
下面这段代码,统计了从 m_PixGroup[uwChannel][wKey] 到 m_PixGroup[uwChannel][wKey + ulLen -1] 中 大于 rBenchMark 的值的个数。
ulCount = std::count_if(m_PixGroup[uwChannel][wKey], m_PixGroup[uwChannel][wKey] + ulLen, [rBenchMark](double x) {return x > rBenchMark;});
int sum = 0;
sum = accumulate(a.begin(), a.end(), sum);
find(a.begin(), a.end(), num_to_find);
int m = *max(a.begin(), a.end()) // 返回的是迭代器
map 和 set 的效率比较高。
int n = 10000000; auto t11 = std::chrono::steady_clock::now(); int* a = new int[n]; for (int i = 0; i < n; ++i) { a[i] = i; } auto t12 = std::chrono::steady_clock::now(); int temp = 0; auto t13 = std::chrono::steady_clock::now(); for (int i = 0; i < n; ++i) { temp = a[i]; } auto t14 = std::chrono::steady_clock::now(); auto t21 = std::chrono::steady_clock::now(); std::vector<int> b; for (int i = 0; i < n; ++i) { b.push_back(i); } auto t22 = std::chrono::steady_clock::now(); auto t23 = std::chrono::steady_clock::now(); for (int i = 0; i < n; ++i) { temp = b[i]; } auto t24 = std::chrono::steady_clock::now(); auto t25 = std::chrono::steady_clock::now(); std::vector<int>::const_iterator it = b.begin(); std::vector<int>::const_iterator it_end = b.end(); //for (; it != b.end(); ++it) // need 7045ms for (; it != it_end; ++ it) { temp = *it; } auto t26 = std::chrono::steady_clock::now(); auto t27 = std::chrono::steady_clock::now(); for (auto i : b) { temp = i; } auto t28 = std::chrono::steady_clock::now(); double a_c = std::chrono::duration<double, std::milli>(t12 - t11).count(); double a_v = std::chrono::duration<double, std::milli>(t14 - t13).count(); double b_c = std::chrono::duration<double, std::milli>(t22 - t21).count(); double b_v = std::chrono::duration<double, std::milli>(t24 - t23).count(); double b_i = std::chrono::duration<double, std::milli>(t26 - t25).count(); double b_a = std::chrono::duration<double, std::milli>(t28 - t27).count(); std::cout << "create array(ms): " << a_c << std::endl; std::cout << "visit array(ms): " << a_v << std::endl; std::cout << "create vector(ms): " << b_c << std::endl; std::cout << "visit vector by index(ms): " << b_v << std::endl; std::cout << "visit vector by iterator(ms): " << b_i << std::endl; std::cout << "visit vector by :(ms): " << b_a << std::endl; delete[] a;
Debug:
Release:
当我们 erase 或者 clear 数据后,vector 的空间(capacity)是没有释放的,可以 通过 swap 或者 shrink_to_fit 释放空间。
// swap std::vector<int> a = { 1,2,3,4 }; std::cout << "size: " << a.size() << " capacity: " << a.capacity() << std::endl; a.erase(a.begin()); std::cout << "size: " << a.size() << " capacity: " << a.capacity() << std::endl; std::vector<int>(a).swap(a); std::cout << "size: " << a.size() << " capacity: " << a.capacity() << std::endl; // a.shrink_to_fit(); a.clear(); std::cout << "size: " << a.size() << " capacity: " << a.capacity() << std::endl; a.shrink_to_fit(); std::cout << "size: " << a.size() << " capacity: " << a.capacity() << std::endl;
以 vector 做为接口时,如果出现 debug, release 混用(B.dll 依赖 Ad.dll), 可能造成兼容性问题。
deque(双端队列)是由一段一段的定量连续空间构成,可以向两端发展,因此不论在尾部或头部安插元素都十分迅速。 在中间部分安插元素则比较费时,因为必须移动其它元素。
deque 与 vector 的用法基本一致,除了以下几处不同:
不能。因为STL的标准容器规定它所容纳的元素必须是可以拷贝构造和可被转移赋值的,而unique_pointer 不能,可以用shared_ptr智能指针代替。
基本都是采用 vector 。如果从性能的角度考虑的话,vector 主要有两个劣势:
针对上面两点可以针对性的避免:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。