c++序列式容器之vector
0.vector源代码
1 // alloc 是SGI STL的空间配置器 2 template<class T,class Alloc=alloc> 3 class vector{ 4 public: 5 //vector的嵌套型别定义 6 typedef T value_type; 7 typedef value_type* pointer; 8 typedef value_type* iterator; 9 typedef value_type* reference; 10 typedef size_t size_type; 11 typedef ptrdiff_t difference_type; 12 protected: 13 //simple_alloc 是SGI STL的空间配置器 14 typedef simple_alloc<value_type,Alloc> data_allocator; 15 iterator start;//表示目前使用空间的头 16 iterator finish;//表示目前使用空间的尾 17 iterator end_of_storage;//表示目前可用空间的尾 18 19 void insert_aux(iterator position,const T& x); 20 void deallocate(){ 21 if(start) 22 data_allocator::deallocate(start,end_of_storage-start); 23 } 24 25 void fill_initialize(size_type n,const T& value) 26 { 27 start=allocate_and_fill(n,value); 28 finish=start+n; 29 end_of_storage=finsih; 30 } 31 32 public: 33 iterator begin(){return start;} 34 iterator end(){return finish;} 35 size_type size() const {return size_type(end()-begin());} 36 size_type capacity() const {return size_type(end_of_storage-begin());} 37 bool empty() const {return begin()==end();} 38 reference operator[](size_type n) {return *(begin()+n);} 39 40 vector():start(0),finish(0),end_of_storage(0){} 41 vector(size_type n,const T& value){fill_initialize(n,value);} 42 vector(int n,const T& value){fill_initialize(n,value);} 43 vector(long n,const T& value){fill_initialize(n,value);} 44 explicit vector(size_type n){fill_initialize(n,T());} 45 46 ~vector(){ 47 destroy(start,finish); 48 deallocate(); 49 } 50 51 reference front(){return *begin();}//第一个元素 52 reference back() {return *(end()-1);}//最后一个元素 53 void push_back(const T& x){//将元素插入至最尾端 54 if(finish!=end_of_storage){ 55 construct(finish,x); 56 ++finish; 57 } 58 else 59 insert_aux(end(),x); 60 } 61 62 void pop_back(){//将最尾端元素取出 63 --finish; 64 destroy(finish);//全局函数 65 } 66 67 iterator erase(iterator position){//清除某位置上的元素 68 if(position+1 !=end) 69 { 70 copy(position+1,finish,position);//后续元素往前移动 71 } 72 --finish; 73 destroy(finish); 74 return position; 75 } 76 77 void resize(size_type new_size,const T& x) 78 { 79 if(new_size<size()) 80 erase(begin()+new_size,end()); 81 else 82 insert(end(),new_size-size(),x); 83 } 84 void resize(size_type new_size){resize(new_size,T());} 85 void clear() {erase(begin(),end());} 86 87 protected: 88 //配置空间并填满内容 89 iterator allocate_and_fill(size_type n,const T& x) 90 { 91 iterator result=data_allocator::allocate(n); 92 uninitialized_fill_n(result,n,x); 93 return result; 94 } 95 };
1.定义和初始化vector对象
vector<T> v1; //v1是一个空vector,执行默认初始化
vector<T> v2(v1) ; //v2中包含v1所有元素的副本
vector<T> v2 = v1; //跟上面等价
vector<T> v3(n, val) ; //v3包含了n个val元素
vector<T> v4(n); //v4中包含n个重复执行了值初始化的对象,值初始化,int型为0,string型为空字符
vector<T> v5{a,b,c...}; //v5中包含了初始值个数的元素,列表初始化 。vector<T> v5(a,b,c..);错误
vector<T> v5 = {a,b,c...}; //同上
vector<int> tmp(vec.begin(), vec.begin() + 3); //用向量vec的第0个到第2个值初始化tmp
例:
vector<int> v1(10); //v1有10个元素都为0
vector<int> v2{10}; //v2有一个元素,为10
vector<int> v3(10,1); //v3有10个元素,都为1
vector<int> v4{10, 1}; //v4有两个元素,为10,1
2.vector的元素操作
(1). 容量
- 向量大小: vec.size();
- 向量最大容量: vec.max_size();
- 更改向量大小: vec.resize();
- 向量真实大小: vec.capacity();
- 向量判空: vec.empty(); //相比vec.size()==0用vec,empty()判断更好
- 减少向量大小到满足元素所占存储空间的大小: vec.shrink_to_fit();
(2). 修改
- 多个元素赋值: vec.assign(); //类似于初始化时用数组进行赋值,其旧元素会被替换
- 末尾添加元素: vec.push_back();
- 末尾删除元素: vec.pop_back();
- 在pos位置插入一个elem元素的拷贝,返回新数据的位置:vec.insert(pos,elem);
- 在pos位置插入n个elem数据,无返回值:vec.insert(pos,n,elem);
- 在pos位置插入[beg,end)区间的数据,无返回值:vec.insert(pos,beg,end);
- 删除指定位置元素: vec.erase(const_iterator position); vec.erase(const_iterator first, const_iterator last);删除指定区间元素
- 交换两个向量的元素: vec.swap();
- 清空向量元素: vec.clear();
(3)迭代器
- 开始指针:vec.begin();
- 末尾指针:vec.end(); //指向最后一个元素的下一个位置
- 指向常量的开始指针: vec.cbegin(); //意思就是不能通过这个指针来修改所指的内容,但还是可以通过其他方式修改的,而且指针也是可以移动的。
- 指向常量的末尾指针: vec.cend();
- 指向向量倒数第一个的指针: vec.rbegin();
- 指向向量倒数最后一个的指针:vec.rend();
(4)元素的访问
- 下标访问: vec[1]; //并不会检查是否越界
- at方法访问: vec.at(1); //以上两者的区别就是at会检查是否越界,是则抛出out of range异常
- 访问第一个元素: vec.front();
- 访问最后一个元素: vec.back();
- 返回一个指针: int* p = vec.data(); //可行的原因在于vector在内存中就是一个连续存储的数组,所以可以返回一个指针指向这个数组。这是是C++11的特性。
例:
assign()
1 // vector assign 2 #include <iostream> 3 #include <vector> 4 5 int main () 6 { 7 std::vector<int> first; 8 std::vector<int> second; 9 std::vector<int> third; 10 11 first.assign (7,100); // 7 ints with a value of 100 12 13 std::vector<int>::iterator it; 14 it=first.begin()+1; 15 16 second.assign (it,first.end()-1); // the 5 central values of first 17 18 int myints[] = {1776,7,4}; 19 third.assign (myints,myints+3); // assigning from array. 20 21 std::cout << "Size of first: " << int (first.size()) << '\n'; 22 std::cout << "Size of second: " << int (second.size()) << '\n'; 23 std::cout << "Size of third: " << int (third.size()) << '\n'; 24 return 0; 25 }
/*ouput
Size of first: 7
Size of second: 5
Size of third: 3
*/
capacity()
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 int main() { 6 vector<int> myvector; 7 for (int i = 0; i < 10; i++) 8 myvector.push_back(i); 9 cout << "size=" << (int)myvector.size() << endl; 10 cout << "capacity=" << (int)myvector.capacity() << endl; 11 cout << "max_size=" << (int)myvector.max_size() << endl; 12 return 0; 13 }
iterator
1 // vector::begin/end 2 #include <iostream> 3 #include <vector> 4 5 int main () 6 { 7 std::vector<int> myvector; 8 for (int i=1; i<=5; i++) myvector.push_back(i); 9 10 std::cout << "myvector contains:"; 11 for (std::vector<int>::iterator it = myvector.begin() ; it != myvector.end(); ++it) 12 std::cout << ' ' << *it; 13 std::cout << '\n'; 14 15 return 0; 16 }
输出:myvector contains: 1 2 3 4 5
const_iterator
1 // vector::cbegin/cend 2 #include <iostream> 3 #include <vector> 4 5 int main () 6 { 7 std::vector<int> myvector = {10,20,30,40,50}; 8 9 std::cout << "myvector contains:"; 10 /* 11 12 for (vector<int> ::const_iterator iter = myvector.cbegin(); iter != myvector.cend(); ++iter) 13 */ 14 15 for (auto it = myvector.cbegin(); it != myvector.cend(); ++it) 16 std::cout << ' ' << *it << std::endl; 17 18 return 0; 19 }
输出:myvector contains: 10 20 30 40 50
reverse_iterator
1 // vector::rbegin/rend 2 #include <iostream> 3 #include <vector> 4 5 int main () 6 { 7 std::vector<int> myvector (5); // 5 default-constructed ints 8 9 int i=0; 10 11 std::vector<int>::reverse_iterator rit = myvector.rbegin(); 12 for (; rit!= myvector.rend(); ++rit) 13 *rit = ++i; 14 15 std::cout << "myvector contains:"; 16 for (std::vector<int>::iterator it = myvector.begin(); it != myvector.end(); ++it) 17 std::cout << ' ' << *it; 18 std::cout << '\n'; 19 20 return
输出:myvector contains: 5 4 3 2 1
const_reverse_iterator
1 // vector::crbegin/crend 2 #include <iostream> 3 #include <vector> 4 5 int main () 6 { 7 std::vector<int> myvector = {1,2,3,4,5}; 8 9 std::cout << "myvector backwards:"; 10 for (auto rit = myvector.crbegin(); rit != myvector.crend(); ++rit) //vector<int>::const_reverse_iterator rit = crbegin; 11 std::cout << ' ' << *rit; 12 std::cout << '\n'; 13 14 return 0; 15 }
输出:myvector backwards: 5 4 3 2 1
const迭代器和const_iterator的区别
前者类似指针常量,指向的地址不可变,但元素内容可变,后者正好相反。
vector<int> vv(10,9);
const vector<int> :: iterator iter = vv.begin();
++iter;//报错
*iter = 10;//正确
vector<int> vv(10,9); vector<int> ::const_iterator iter ; for(iter = vv.begin(); iter != vv.end(); ++iter){ cout << *iter << endl; } //这是正确的,iter本身的值是可以改变的 /* for(iter = vv.begin(); iter != vv.end(); ++ iter){ *iter = 0; }//这是错误的 */
data
1 // vector::data 2 #include <iostream> 3 #include <vector> 4 5 int main () 6 { 7 std::vector<int> myvector (5); 8 9 int* p = myvector.data(); 10 11 *p = 10; 12 ++p; 13 *p = 20; 14 p[2] = 100; 15 16 std::cout << "myvector contains:"; 17 for (unsigned i=0; i<myvector.size(); ++i) 18 std::cout << ' ' << myvector[i]; 19 std::cout << '\n'; 20 21 return 0; 22 }
输出:myvector contains: 10 20 0 100 0
emplace
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 void note(int a, int b, long int c) { 6 cout << "size=" << a << endl; 7 cout << "capacity=" << b << endl; 8 cout << "max_size=" << c << endl; 9 } 10 int main() { 11 vector<int> myvector{10,20,30}; 12 cout << "origin:"; 13 for (auto& i: myvector) cout << ' ' << i; 14 cout << endl; 15 16 note(myvector.size(), myvector.capacity(), myvector.max_size()); 17 18 myvector.emplace(myvector.begin()+2, 1); 19 cout << "----first modify----" << endl; 20 for(auto& i: myvector) 21 cout << ' ' << i; 22 cout << endl; 23 24 note(myvector.size(), myvector.capacity(), myvector.max_size()); 25 26 auto it = myvector.emplace(myvector.begin()+1, 100); 27 myvector.emplace(it, 666); 28 cout << "---second modify---" << endl; 29 for (; it < myvector.end()-1; it++) 30 cout << ' ' << *it; 31 cout << endl; 32 33 note(myvector.size(), myvector.capacity(), myvector.max_size()); 34 35 myvector.emplace(it, 200); 36 cout << "---third modify---" << endl; 37 for (auto& j: myvector) 38 cout << " " << j; 39 cout << "\n"; 40 note(myvector.size(), myvector.capacity(), myvector.max_size()); 41 cout << "-----last-----" << endl; 42 myvector.emplace(myvector.end(), 300); 43 for (auto& x: myvector){ 44 cout << ' ' << x; 45 } 46 cout << endl; 47 note(myvector.size(),myvector.capacity(), myvector.max_size()); 48 return 0; 49 }
//vector<int>::iterator it = myvector.emplace(myvector.emplace.end(), 1);
emplace_back
1 // vector::emplace_back 2 #include <iostream> 3 #include <vector> 4 5 int main () 6 { 7 std::vector<int> myvector = {10,20,30}; 8 9 myvector.emplace_back (100); 10 myvector.emplace_back (200); 11 12 std::cout << "myvector contains:"; 13 for (auto& x: myvector) 14 std::cout << ' ' << x; 15 std::cout << '\n'; 16 17 return 0; 18 }
输出:myvector contains: 10 20 30 100 200
erase
1 // erasing from vector 2 #include <iostream> 3 #include <vector> 4 5 int main () 6 { 7 std::vector<int> myvector; 8 9 // set some values (from 1 to 10) 10 for (int i=1; i<=10; i++) myvector.push_back(i); 11 12 // erase the 6th element 13 myvector.erase (myvector.begin()+5); 14 15 // erase the first 3 elements: 16 myvector.erase (myvector.begin(),myvector.begin()+3); 17 18 std::cout << "myvector contains:"; 19 for (unsigned i=0; i<myvector.size(); ++i) 20 std::cout << ' ' << myvector[i]; 21 std::cout << '\n'; 22 23 return 0; 24 } 25 Edit & Run
输出:myvector contains: 4 5 7 8 9 10