数据结构:研究节点和节点之间的关系
STL(算法、容器、迭代器)实现了数据结构和算法的有效分离,用来管理元素。算法和迭代器可以进行无缝连接
count(v.begin(),v.end(),3)//统计元素3的个数
容器除了可以放基础数据类型,也可以放元素(类类型对象),也可以放指针类型,也可以放指针类类型对象【涉及深拷贝和浅拷贝】。
容器push_back()是将元素拷贝到容器中,所以要确保元素可以被复制,即如果是类对象的话拷贝构造函数。
容器分类:
序列式容器(Sequence containers)
每个元素都有固定位置--取决于插入时机和地点,和元素值无关。vector、deque、list
关联式容器(Associated containers)
元素位置取决于特定的排序准则,和插入顺序无关 set、multiset、map、multimap
常用算法头文件:<algorithm>,<numeric>和<functional>
一、容器
1.string
1.1存取字符:operator[]和at()//主要区别在于at()在越界时会抛出异常,[]在刚好越界时会返回(char)0,再继续越界时,编译器直接出错。如果你的程序希望可以通过try,catch捕获异常,建议采用at()。
1.2 string转char*
const char *c_str() const; //从string取得char* 返回一个以'\0'结尾的字符串的首地址
int copy(char *s, int n, int pos=0) const; //把string拷贝到char*,s要分配内存
1.3长度
int length() const; //返回当前字符串的长度。长度不包括字符串结尾的'\0'。
bool empty() const; //当前字符串是否为空
1.4赋值
string &operator=(const string &s);//把字符串s赋给当前的字符串,s可以是const string &,const char *
string &assign(s); //把字符串s赋给当前的字符串,可以是const string &,const char *
string &assign(const char *s, int n); //把字符串s的前n个字符赋给当前的字符串
string &assign(int n,char c); //用n个字符c赋给当前字符串
string &assign(const string &s,int start, int n); //把字符串s中从start开始的n个字符赋给当前字符串
1.5比较
int compare(s) const; //与字符串s比较,s可以是const string &,const char *
compare函数在>时返回 1,<时返回 -1,==时返回 0。比较区分大小写,比较时参考字典顺序,排越前面的越小。大写的A比小写的a小。
1.6字串
string substr(int pos=0, int n=npos) const; //返回由pos开始的n个字符组成的子字符串
1.7查找与替换
查找
int find(char c,int pos=0) const; //从pos开始查找字符c在当前字符串的位置
int find(s, int pos=0) const; //从pos开始查找字符串s在当前字符串的位置,s可以是const string &,const char *
int rfind(char c, int pos=npos) const; //从pos开始从后向前查找字符c在当前字符串中的位置
int rfind(s, int pos=npos) const;//npos最后一个位置
//rfind是反向查找的意思,如果查找不到, 返回-1
替换
string &replace(int pos, int n, s);//删除从pos开始的n个字符,然后在pos处插入串s
void swap(string &s2); //交换当前字符串与s2的值
1.8区间删除和插入
string &insert(int pos, s);//前两个函数在pos位置插入字符串s
string &insert(int pos, int n, char c); //在pos位置 插入n个字符c
string &erase(int pos=0, int n=npos); //删除pos开始的n个字符,返回修改后的字符串
1.9算法
transform(起始位置,结束位置,目标起始地址,回调函数地址)//替换比如toUpper/toLower
2.Vector动态数组
2.1构造
vector采用模板类实现,vector对象的默认构造形式
vector<T> vecT;
Class CA{};
vector<CA*> vecpCA; //用于存放CA对象的指针的vector容器。
vector<CA> vecCA; //用于存放CA对象的vector容器。由于容器元素的存放是按值复制的方式进行的,所以此时CA必须提供CA的拷贝构造函数,以保证CA对象间拷贝正常。
带参数构造
vector(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身。注意该区间是左闭右开的区间。
vector(n,elem); //构造函数将n个elem拷贝给本身。
vector(const vector &vec); //拷贝构造函数
2.2赋值
vector.assign(beg,end); //将[beg, end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间。
vector.assign(n,elem); //将n个elem拷贝赋值给本身。
vector& operator=(const vector &vec); //重载等号操作符
vector.swap(vec); // 将vec与本身的元素互换。
2.3大小
vector.size(); //返回容器中元素的个数
vector.empty(); //判断容器是否为空
vector.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
vector.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
2.4末尾添加、移除
vecInt.push_back(1); //在容器尾部加入一个元素
vecInt.pop_back();//移除
2.5数据存取
vec.at(idx); //返回索引idx所指的数据,如果idx越界,抛出out_of_range异常。
vec[idx]; //返回索引idx所指的数据,越界时,运行直接报错
2.6插入
vector.insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置。
vector.insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值。
vector.insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值
2.7删除
vector.clear(); //移除容器的所有数据
vec.erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。
vec.erase(pos); //删除pos位置的数据,返回下一个数据的位置。
//这样程序会跑宕,因为最初没有分配内存直接赋值会出错,将第一句定义改为vector<int> vec(10);ok
2.8迭代器
正向遍历:
for(vector<int>::iterator it=vecInt.begin(); it!=vecInt.end(); ++it)
{
int iItem = *it;
cout << iItem; //或直接使用 cout << *it;
}
//存储Teacher类指针类型元素
for(vector<Teacher*>::iterator it=vecInt.begin(); it!=vecInt.end(); ++it)
{
cout << (*it)->age; //访问指针类类型元素的方式(*it)->age.
}
逆向+r
2.9删除指定元素
for(vector<int>::iterator it=vecInt.begin(); it!=vecInt.end(); )
{
if(*it==2)
it=v1.erase(it);
//当删除迭代器所指向的元素的时候,erase删除函数会让it自动向下移动,所以只在不等的时候++,返回一个迭代器的位置,所以要用新的it接住
else
it++;
}
2.10 宕机实例
vector<int> vec;
for(int i=0;i<10;i++)
vec[i]=i+1;
3.deque双端数组
3.1头部和末尾的添加移除
deque.push_back(elem); //在容器尾部添加一个数据
deque.push_front(elem); //在容器头部插入一个数据
deque.pop_back(); //删除容器最后一个数据
deque.pop_front(); //删除容器第一个数据
3.2大部分基本操作与vector相同
数据存取、迭代器、赋值、带参构造函数、大小、插入、删除与vector相同
3.3根据迭代器求数组下标
#include <deque>
#include <algorithm>
deque<int>::it=find(d1.begin(),d1.end(),-33);
if(it!=d1.end())
cout<<"-33的下标是"<<distance(d1.begin(),it)<<endl;//diatance函数计算两个迭代器之间的距离
else
cout<<"未找到值为-33的元素"<<endl;
4.stack容器
4.1默认构造
stack采用模板类实现, stack对象的默认构造形式: stack <T> stkT;
4.2push和pop
stack.push(elem); //往栈头添加元素
stack.pop(); //从栈头移除第一个元素
4.3拷贝构造和赋值
stack(const stack &stk); //拷贝构造函数
stack& operator=(const stack &stk); //重载等号操作符
4.4获取栈顶元素
stack.top(); //返回最后一个压入栈元素
4.5大小
stack.empty(); //判断堆栈是否为空
stack.size(); //返回堆栈的大小
5.queue
5.1默认构造
queue采用模板类实现,queue对象的默认构造形式:queue<T> queT;
5.2push与pop
queue.push(elem); //往队尾添加元素
queue.pop(); //从队头移除第一个元素
5.3拷贝构造与赋值
queue(const queue &que); //拷贝构造函数
queue& operator=(const queue &que); //重载等号操作符
5.4back和front
queue.back(); //返回最后一个元素
queue.front(); //返回第一个元素
5.5大小
queue.empty(); //判断队列是否为空
queue.size(); //返回队列的大小
6.List容器 双向链表容器
6.1简介
可以高效的进行插入删除元素,不可以随机存取元素所以不支持at(pos)函数,支持it++,it--但不支持it+5
6.2头尾的添加移除
list.push_back(elem); //在容器尾部加入一个元素
list.pop_back(); //删除容器中最后一个元素
list.push_front(elem); //在容器开头插入一个元素
list.pop_front(); //从容器开头移除第一个元素
6.3数据存取
list.front(); //返回第一个元素。
list.back(); //返回最后一个元素。
6.4带参构造函数
list(beg,end); //构造函数将[beg, end)区间中的元素拷贝给本身。注意该区间是左闭右开的区间。
list(n,elem); //构造函数将n个elem拷贝给本身。
list(const list &lst); //拷贝构造函数。
6.5赋值
list.assign(beg,end); //将[beg, end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间。
list.assign(n,elem); //将n个elem拷贝赋值给本身。
list& operator=(const list &lst); //重载等号操作符
list.swap(lst); // 将lst与本身的元素互换。
6.6大小
list.size(); //返回容器中元素的个数
list.empty(); //判断容器是否为空
list.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
list.resize(num, elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。
6.7插入
list.insert(pos,elem); //在pos位置插入一个elem元素的拷贝,返回新数据的位置。
list.insert(pos,n,elem); //在pos位置插入n个elem数据,无返回值。
list.insert(pos,beg,end); //在pos位置插入[beg,end)区间的数据,无返回值。
6.8删除
list.clear(); //移除容器的所有数据
list.erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。
list.erase(pos); //删除pos位置的数据,返回下一个数据的位置。
lst.remove(elem); //删除容器中所有与elem值匹配的元素。
6.9反序排列
lst.reverse(); //反转链表,比如lst包含1,3,5元素,运行此方法后,lst就包含5,3,1元素。