第八周 标准模板库STL(一)
1.string类
2.标准模板库STL概述(一)
3.标准模板库STL概述(二)
4.vector,deque和list
5.函数对象
4.vector,deque和list
vector可变长数组
根据下标访问时间复杂度是O(1),常量时间,在尾部添加、删除元素的时间复杂度是O(1),在中间添加、删除元素的时间复杂度是O(n)。以下是几个关于vector构造函数、insert、erase的例子,还有其他很多成员函数,可以查STL手册。
例子:vector构造函数、insert、erase
#include <iostream>
#include <vector>
using namespace std;
template<class T>
void PrintVector( T s, T e)
{
for(; s != e; ++s)
cout << * s << " ";
cout << endl;
}
int main() {
int a[5] = { 1,2,3,4,5 };
vector<int> v(a,a+5); //构造函数,将数组a的内容放入v,a+5是最后一个元素的下一个,不在数组内,所有这样的区间,都是左闭右开,不包括后面那个的
cout << "1) " << v.end() - v.begin() << endl;
//两个随机迭代器可以相减,输出: 1) 5
cout << "2) "; PrintVector(v.begin(),v.end());
//2) 1 2 3 4 5
v.insert(v.begin() + 2, 13); //插入一个元素,在begin()+2位置插入 13
cout << "3) "; PrintVector(v.begin(),v.end());
//3) 1 2 13 3 4 5
v.erase(v.begin() + 2); //删除一个元素,删除位于 begin() + 2的元素
cout << "4) "; PrintVector(v.begin(),v.end());
//4) 1 2 3 4 5
vector<int> v2(4,100); ///构造函数,v2 有4个元素,都是100
v2.insert(v2.begin(),v.begin()+ 1,v.begin()+3);//插入一个区间,将v的一段插入v2开头
cout << "5) v2: "; PrintVector(v2.begin(),v2.end());
//5) v2: 2 3 100 100 100 100
v.erase(v.begin() + 1, v.begin() + 3);//删除一个区间,删除 v 上的一个区间,即 2,3
cout << "6) "; PrintVector(v.begin(),v.end());
//6) 1 4 5
return 0;
}
例子:vector二维数组 vector<vector空格> v;这里的空格是为了防止有些编译器把两个尖括号连成右移运算符。vector二维数组的每个元素v[i]都是vector一位数组,且长度可以不一样。访问元素v[i][j]。
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector<vector<int> > v(3);//v 有3 个元素,每个元素都是vector<int> 容器
for(int i = 0;i < v.size(); ++i)
for(int j = 0; j < 4; ++j)
v[i].push_back(j);
for(int i = 0;i < v.size(); ++i) {
for(int j = 0; j < v[i].size(); ++j)
cout << v[i][j] << " ";
cout << endl;
}
return 0;
}
程序输出结果:
0 1 2 3
0 1 2 3
0 1 2 3
deque双向队列
所有适用于 vector的操作都适用于 deque。
deque还有 push_front(将元素插入到前面)和pop_front(删除最前面的元素)操作,复杂度是O(1)。
list双向链表
在任何位置插入删除都是常数时间,不支持随机存取。除了具有所有顺序容器都有的成员函数以外,还支持8个成员函数:
push_front: 在前面插入
pop_front: 删除前面的元素
sort: 排序 ( list 不支持 STL 的算法 sort,list有自己的sort排序成员函数)
remove: 删除和指定值相等的所有元素
unique: 删除所有和前一个元素相同的元素(要做到元素不重复,则unique之前还需要 sort)
merge: 合并两个链表,并清空被合并的那个
reverse: 颠倒链表
splice: 在指定位置前面插入另一链表中的一个或多个元素,并在另一链表中删除被插入的元素
例子:
#include <list>
#include <iostream>
#include <algorithm>
using namespace std;
class A {
private:
int n;
public:
A( int n_ ) { n = n_; }
friend bool operator<( const A & a1, const A & a2);
friend bool operator==( const A & a1, const A & a2);
friend ostream & operator <<( ostream & o, const A & a);
};
bool operator<( const A & a1, const A & a2) {
return a1.n < a2.n;
}
bool operator==( const A & a1, const A & a2) {
return a1.n == a2.n;
}
ostream & operator <<( ostream & o, const A & a) {
o << a.n;
return o;
}
template <class T>
void PrintList(const list<T> & lst) {
//不推荐的写法,还是用两个迭代器作为参数更好
int tmp = lst.size();
if( tmp > 0 ) {
typename list<T>::const_iterator i;
i = lst.begin();
for( i = lst.begin();i != lst.end(); i ++)
cout << * i << ",";
}
}// typename用来说明 list<T>::const_iterator是个类型,在vs中不写也可以
int main() {
list<A> lst1,lst2;
lst1.push_back(1);lst1.push_back(3);//调用了类A的类型转换构造函数
lst1.push_back(2);lst1.push_back(4);
lst1.push_back(2);
lst2.push_back(10);lst2.push_front(20);
lst2.push_back(30);lst2.push_back(30);
lst2.push_back(30);lst2.push_front(40);
lst2.push_back(40);
cout << "1) "; PrintList( lst1); cout << endl;
// 1) 1,3,2,4,2,
cout << "2) "; PrintList( lst2); cout << endl;
// 2) 40,20,10,30,30,30,40,
lst2.sort();
cout << "3) "; PrintList( lst2); cout << endl;
//3) 10,20,30,30,30,40,40,
lst2.pop_front();
cout << "4) "; PrintList( lst2); cout << endl;
//4) 20,30,30,30,40,40,
lst1.remove(2); //2会自动转换成类A的对象,删除所有和A(2)相等的元素
cout << "5) "; PrintList( lst1); cout << endl;
//5) 1,3,4,
lst2.unique(); //删除所有和前一个元素相等的元素
cout << "6) "; PrintList( lst2); cout << endl;
//6) 20,30,40,
lst1.merge (lst2); //合并 lst2到lst1并清空lst2
cout << "7) "; PrintList( lst1); cout << endl;
//7) 1,3,4,20,30,40,
cout << "8) "; PrintList( lst2); cout << endl;
//8)
lst1.reverse();
cout << "9) "; PrintList( lst1); cout << endl;
//9) 40,30,20,4,3,1,
lst2.push_back (100);lst2.push_back (200);
lst2.push_back (300);lst2.push_back (400);
list<A>::iterator p1,p2,p3;
p1 = find(lst1.begin(),lst1.end(),3);
p2 = find(lst2.begin(),lst2.end(),200);
p3 = find(lst2.begin(),lst2.end(),400);
lst1.splice(p1,lst2,p2, p3);
//将[p2,p3)插入p1之前,并从lst2中删除[p2,p3)
cout << "10) "; PrintList( lst1); cout << endl;
//10) 40,30,20,4,200,300,3,1,
cout << "11) "; PrintList( lst2); cout << endl;
//11) 100,400,
return 0;
}