注意:c++的容器类在使用时尽量使用迭代器去遍历!
常用算法函数
包含在头文件#include <algorithm>
中.
//对a中的从a.begin()(包括它)到a.end()(不包括它)的元素进行从小到大排列
1)sort(a.begin(),a.end());
//对a中的从a.begin()(包括它)到a.end()(不包括它)的元素倒置,但不排列,如a中元素为1,3,2,4,倒置后为4,2,3,1
(2)reverse(a.begin(),a.end());
//把a中的从a.begin()(包括它)到a.end()(不包括它)的元素复制到b中,从b.begin()+1的位置(包括它)开 始复制,覆盖掉原有元素
(3)copy(a.begin(),a.end(),b.begin()+1);
//在a中的从a.begin()(包括它)到a.end()(不包括它)的元素中查找10,若存在返回其在向量中的位置
(4)find(a.begin(),a.end(),10);
vector容器
vector 是向量类型,它可以容纳许多类型的数据,如若干个整数,所以称其为容器。vector 是C++ STL的一个重要成员,使用它时需要包含头文件#include <vector>
.
一、vector 的初始化:可以有五种方式,举例说明如下:
(1) vector<int> a(10); //定义了10个整型元素的向量(尖括号中为元素类型名,它可以是任何合法的数据类型),但没有给出初值,其值是不确定的。
(2)vector<int> a(10,1); //定义了10个整型元素的向量,且给出每个元素的初值为1
(3)vector<int> a(b); //用b向量来创建a向量,整体复制性赋值
(4)vector<int> a(b.begin(),b.begin+3); //定义了a值为b中第0个到第2个(共3个)元素
(5)int b[7]={1,2,3,4,5,9,8};
vector<int> a(b,b+7); //从数组中获得初值
二、vector对象的几个重要操作,举例说明如下:
(1)a.assign(b.begin(), b.begin()+3); //b为向量,将b的0~2个元素构成的向量赋给a
(2)a.assign(4,2); //是a只含4个元素,且每个元素为2
(3)a.back(); //返回a的最后一个元素
(4)a.front(); //返回a的第一个元素
(5)a[i]; //返回a的第i个元素,当且仅当a[i]存在
(6)a.clear(); //清空a中的元素
(7)a.empty(); //判断a是否为空,空则返回ture,不空则返回false
(8)a.pop_back(); //删除a向量的最后一个元素
(9)a.erase(a.begin()+1,a.begin()+3); //删除a中第1个(从第0个算起)到第2个元素,也就是说删除的元素从a.begin()+1算起(包括它)一直到a.begin()+3(不包括它)
(10)a.push_back(5); //在a的最后一个向量后插入一个元素,其值为5
(11)a.insert(a.begin()+1,5); //在a的第1个元素(从第0个算起)的位置插入数值5,如a为1,2,3,4,插入元素后为1,5,2,3,4
(12)a.insert(a.begin()+1,3,5); //在a的第1个元素(从第0个算起)的位置插入3个数,其值都为5
(13)a.insert(a.begin()+1,b+3,b+6); //b为数组,在a的第1个元素(从第0个算起)的位置插入b的第3个元素到第5个元素(不包括b+6),如b为1,2,3,4,5,9,8 ,插入元素后为1,4,5,9,2,3,4,5,9,8
(14)a.size(); //返回a中元素的个数;
(15)a.capacity(); //返回a在内存中总共可以容纳的元素个数
(16)a.resize(10); //将a的现有元素个数调至10个,多则删,少则补,其值随机
(17)a.resize(10,2); //将a的现有元素个数调至10个,多则删,少则补,其值为2
(18)a.reserve(100); //将a的容量(capacity)扩充至100,也就是说现在测试a.capacity();的时候返回值是100.这种操作只有在需要给a添加大量数据的时候才 显得有意义,因为这将避免内存多次容量扩充操作(当a的容量不足时电脑会自动扩容,当然这必然降低性能)
(19)a.swap(b); //b为向量,将a中的元素和b中的元素进行整体性交换
(20)a==b; //b为向量,向量的比较操作还有!=,>=,<=,>,<
三、顺序访问vector的几种方式,举例说明如下:
vector<int> a;
for(int i=0;i<10;i++)
a.push_back(i); //注意添加元素使用push_back()方法,不能直接使用a[i]去赋值。
四 、遍历vector
// 方式一,迭代器
int a[6]={1,2,3,4,5,6};
vector<int> b(a,a+4);
for(vector<int>::iterator it=b.begin();it!=b.end();it++)
cout<<*it<<" ";
// 方式二,常规方法
for (int i = 0; i<b.size(); ++i){
cout<<b[i]<<endl;
}
二维数组遍历:(最好使用迭代器遍历,动态数组很可能大小不一,例如下例则不能使用普通for循环遍历)
vector<int> c={2,3,6,7};
vector<int> d={3,4,5};
vector<vector<int>> ans;
ans.push_back(c);
ans.push_back(d);
vector<vector<int>> :: iterator it;
for(it=ans.begin();it!=ans.end();it++)
{
for (int i = 0; i < (*it).size(); ++i)
cout << (*it)[i] << " " ;
cout<<endl;
}
注意,在二维vector操作中,若只使用模板方法,可以不用初始化数组大小,但若要使用下标来进行相关操作,则最好初始化数组大小,如以下情形:
vector<vector<int>> matrix(1,vector<int>(1));
matrix[0].push_back(4);
matrix[0].push_back(5);
vector<vector<int>> :: iterator it;
for(it=matrix.begin();it!=matrix.end();it++){
for (int i = 0; i < (*it).size(); ++i)
cout << (*it)[i] << " " ;
cout<<endl;
}
set容器
set是C++标准库中的一种关联容器。所谓关联容器就是通过键(key)来读取和修改元素。与map关联容器不同,它只是单纯键的集合。
set集合容器实现了红黑树(Red-Black Tree)的平衡二叉检索树的数据结构,在插入元素时,它会自动调整二叉树的排列,把该元素放到适当的位置,以确保每个树根节点的键值大于左子树所有节点的键值,而小于右子树所有节点的键值;另外,还确保根节点左子树的高度与右子树的高度相等,这样,二叉树的高度最小,从而检索速度最快。要注意的是,它不会重复插入相同键值的元素,而采取忽略处理。
特点:有序、不重复、红黑树
注意:vector中添加元素使用push_back(),set中添加元素使用insert().
;
头文件:#include<set>
set集合基本操作
s.begin() // 返回指向第一个元素的迭代器
s.clear() // 清除所有元素
s.count() // 返回某个值元素的个数
s.empty() // 如果集合为空,返回true(真)
s.end() // 返回指向最后一个元素之后的迭代器,不是最后一个元素
s.equal_range() // 返回集合中与给定值相等的上下限的两个迭代器
s.erase() // 删除集合中的元素
s.find() // 返回一个指向被查找到元素的迭代器
s.get_allocator() // 返回集合的分配器
s.insert() // 在集合中插入元素
s.lower_bound() // 返回指向大于(或等于)某值的第一个元素的迭代器
s.key_comp() // 返回一个用于元素间值比较的函数
s.max_size() // 返回集合能容纳的元素的最大限值
s.rbegin() // 返回指向集合中最后一个元素的反向迭代器
s.rend() // 返回指向集合中第一个元素的反向迭代器
s.size() // 集合中元素的数目
s.swap() // 交换两个集合变量
s.upper_bound() // 返回大于某个值元素的迭代器
s.value_comp() // 返回一个用于比较元素间的值的函数
注意:在for循环中,结束条件为for(it=s.begin();it!=s.end();it++)
,是!=
set的遍历:迭代器
#include<iostream>
#include<set>
using namespace std;
set<int>s;
int main()
{
s.insert(1);
s.insert(2);
s.insert(3);
set<int>::iterator it;
for(it=s.begin();it!=s.end();it++)
{
cout<<*it<<" ";
}
cout<<endl;
}
map容器
Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的,后边我们会见识到有序的好处。
根据key值快速查找记录,查找的复杂度基本是Log(N)
//用数组方式插入数据,下面举例说明
#include <map>
#include <string>
#include <iostream>
using namespace std;
int main()
{
map<int, string> mapStudent;
mapStudent[1] = "78";
mapStudent[2] = "100";
mapStudent.insert({5,"90"});
//mapStudent[3] = "80";
map<int, string>::iterator iter;
for(iter = mapStudent.begin();iter!=mapStudent.end();iter++)
cout<<iter->first<<' '<<iter->second<<endl;
}
stack容器
stack的基本操作有:
1.入栈:如s.push(x);
2.出栈:如 s.pop().注意:出栈操作只是删除栈顶的元素,并不返回该元素。
3.获得栈顶元素:如s.top();
4.判断栈空:如s.empty().当栈空时返回true。
5.访问栈中的元素个数,如s.size();
queue容器
#include<queue>
queue<int> q1;//定义一个类型为int的队列
q1.push(x);//将x连接到队列的尾端
q1.pop();//弹出队列的第一个元素,但并不返回它
q1.front();//返回队首元素
q1.back();//返回队尾元素
q1.empty();//判断队列是否为空,若是返回1
q1.size();//返回队列长度
//定义一个元素为结构体的队列
struct node
{int x,y;};
queue<node> q;
string容器
string类可以直接使用+进行字符串拼接;
有substr()用来提取子串;
string类型不可以用printf("%s",str);
仍然可以使用cout;
可以使用strlen(s)
来获取char[]
的长度
注意:
c++中,cout<<1+"";cout<<""+1;
什么输出都没有;
若想实现字符串连接数字,例如在"hello"后面加上"2",可以
string str="123";str= str + (char)(2+'0')
此处的强制转换必须有,因为2+'0'
将自动转化为数字2对应的Ascll值。
另外,直接加char的字符转化成字符串是可以的,例如:
string str="hello";
char x=str[0]; // 输出“h”
此外还可以使用string的 to_string()
函数实现数字转化成字符串(不需额外添加头文件)
string str="1";
int x=10;
str=str+to_string(x);
cout<<str; // 输出为110
另外,char[]
转换成数字有以如下方法:
char x[]="1645";
int ans=atoi(x);
cout<<ans; // 输出1645