1.#include<algorithm>
sort排序
在C++中自带的排序函数,对数组中任意连续切片进行排序。
头文件#include<algorithm>
例如有数组A[1000]
- 对数组从A[a]到A[b-1]进行升序排序:
sort(A+a,A+b)
- 对数组从A[a]到A[b-1]进行降序排序:
sort(A+a,A+b,greater<int>())
其中,greater<int>()
表示降序排序数据类型为int的元素
#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e6+10;
int a[N];
int main()
{
for(int i = 0; i < 10; i++) cin >> a[i];
sort(a+1,a+9);
for(int i = 0; i < 10; i++) cout << a[i] << " ";
cout << endl;
sort(a+1,a+9,greater<int>());
for(int i = 0; i < 10; i++) cout << a[i] << " ";
cout << endl;
return 0;
}
swap()函数
swap 参数是引用的,不需要取地址。
int num[4] = {0,1,2,3};
swap(num[0],num[3]);
reverse()函数
反转一个可迭代对象的元素顺序,比如数组。
使用reverse(num+a,num+b);
可以反转切片
int num[4] = {0,1,2,3};
reverse(num,num+4);
max() & min()
使用max(a,b)
& min(a,b)
甚至还可以max({1,2,3,4})
?里面是一个数组的形式…
写在中间
- 大多数标准容器都提供
.swap()
成员函数,一般用于交换两个容器的内容; - 对于清空容器,某些容器没有成员函数
.clear()
,可以使用直接赋值为空的方法:
stack<int> S1 = stack<int>();
set<double> Set1 = set<double>();
2.#include<vector>
动态数组相关
- 开局:
#include<vector>
using namespace std;
int main()
{...}
开数组
- 定义:
vector<数据类型> name
数据类型可以是int\float\double…vector<int> a
就定义了一个储存整数的动态数组a,不用设置大小。
访问元素
直接访问a[1]…
在末尾插入元素
使用 数组名.push_back(新元素);
#include <vector>
using namespace std;
vector<int> a;//[]
int main()
{
a.push_back(1);//[1]
a.push_back(2);//[1,2]
...
return 0;
}
获取长度
使用 数组名.size()
#include <vector>
using namespace std;
vector<int> a;
int main()
{
...
for(int i = 0; i < a.size(); i ++)
cout << a[i];
return 0;
}
修改元素
直接修改a[1] = 9; ... a[1] = 3;
从末尾删除元素
使用 数组名.pop_back();
因为从内部某处删除元素还得涉及到元素的整体移动。
清空所有元素
无需一个一个.pop_back()
,使用 数组名.clear()
判断vector是否为空
使用 数组名.empty()
,返回一个bool值,true为空。
改变数组的长度
使用 数组名.resize(修改后的长度,初值);
若是改长数组,初值是赋给多出来的部分;如果不写初值新多出来的长度默认为0;
如果是改短,之间删除原有的,变为空;
访问尾下标
使用 数组名,back()
使用库<algorithm>
的sort函数进行排序
- 对于
vector<int>
是对大小进行升序排序 - 对于
vector<string>
是对字符串进行字典序的升序排序
动态数组储存自定义数据
除了储存基本数据类型,还可以储存自定义的数据类型,比如结构体。
#include<iostream>
#include <vector>
#include<string>
using namespace std;
struct Student
{
int age;
string name;
int Class;
};
vector<Student> a;
int main()
{
Student s1,s2;
s1.age = 19;
s1.name = "xiaoguang";
s1.Class = 2;
s2.age = 18;
s2.name = "xiaohong";
s2.Class = 1;
a.push_back(s1);
a.push_back(s2);
cout << a.size();
return 0;
}
构造函数快速创建动态数组
使用vector<int> num(长度,初始值);
直接初始化一个已经具有长度且全部都是初始值的动态数组。
括号中具有两个参数,如果省略初始值,那么初始值默认为0;如果同时省略长度和初始值,那么num是空的,不可访问。
int n = 10;
vector<int> nums1(n,6);
//开了一个已经有10个元素6的动态数组。
vector<int> nums2;
动态二维数组
使用vector<vector<int> > 数组名
。可以理解为开辟的数组里面放的是数组。动态二维数组可以是不等长的。
- 快速构建
vector<vector<int> > num(行数,vector<int>(列数,0))
包含行数、列数、初值
#include<iostream>
#include<vector>
using namespace std;
vector<vector<int>> vec1(2,vector<int>(3,0))
大小还是可以再变的,只不过一开始初始化就有下面:
-
比如
vector<vector<int>> A(N);
定义了一个二维数组,一共有N行,每行的列数是动态变化的 -
矩阵:
#include<iostream>
#include<vector>
using namespace std;
vector<vector<int> > num;
vector<int> num1;
vector<int> num2;
int main()
{
num1.push_back(1);
num1.push_back(2);
num2.push_back(3);
num2.push_back(4);
num.push_back(num1);
num.push_back(num2);
for(int i = 0; i < num.size(); i ++)
{
for(int j = 0; j < num[i].size(); j++)
{
cout << num[i][j] << " ";
}
cout << endl;
}
return 0;
}
输出为2x2的矩阵:
1 2
3 4
3.#include<set>
集合
开局:
#include<set>
using namespace std;
创建集合
使用set<数据类型> 集合名
储存相同数据类型的数据,初始化成功之后集合是空的,注意集合中元素不可以重复
set<int> s1;
set<string> s23;
插入元素
使用 集合名.insert(要插入的元素);
在集合末尾插入一个新的元素,如果要插入的元素在集合已经存在,那么将不会执行任何操作(也不会报错)。
删除元素
使用 集合名.erase(要删除的元素);
判断元素是否存在
使用 集合名.count(要判断的元素)
这是一个表达式,如果存在返回1,不存在返回0.
遍历集合
使用set<数据类型>::iterator it;
定义一个迭代器。定义迭代器可以直接使用auto it;
注意集合名.begin()
返回容器中起始元素的迭代器,集合名.end()
函数返回容器的尾后迭代器。
注意遍历set是从小到大进行遍历的,也就是自动排好序了。
set<int> set1 = {"a","b","c"};
for set<int>::iterator it = set1.begin(); it != set1.end(); it ++)
{
cout << *it << endl;
}
- 这里可以把
set<int>::iterator
看做一种数据类型,就像for(int i = 0;...)
; - 输出的时候要解引用
*it
。 - 尽管添加元素到集合的时候是无序的,但是遍历元素的时候打印出来的集合元素师有序排列的。
int、float
类数据按照大小进行排序;char、string
类数据则按照字典序进行排序,即从第一个字符开始,逐个字符比较两个字符串的 ASCII 值。
清空集合
使用 集合名.clear();
会清空结合中的元素,同时释放掉set占用的内存。
代码示例:
#include<iostream>
#include<set>
#include<string>
using namespace std;
int main()
{
set<string> S1 = {"China","USA","England"};
S1.insert("US");
S1.erase("China");
if(S1.count("China"))
{
cout << "China is in the set."<<endl;
}
for(set<string>::iterator it = S1.begin(); it != S1.end(); it ++)
{
cout << *it << " ";
}
cout << endl;
return 0;
}
输出为:England US USA
4.#include<map>
映射
映射是指两个集合之间的相互对应关系。
类似python中的字典,一个key只能对应一个value,不同的key的value可以相同。
映射的关键字是map
,在map中是以pair<>的方式储存的
创建映射
使用map<key,value> 映射名;
.其中key和value都是某种数据结构,如map<name,class> Class1;
。初始建立的map是空映射。
添加键值pair
- 使用
map名.insert(键值pair);
- 键值pair有两种方法建立:1.
make_pair(key,value)
该表达式返回一对键值pair;
一般使用2.直接添加映射名[key] = value;
- 如果要插入的key已经存在,那么插入无效。
访问映射的key
- 访问的方式和数组一样,使用
[]
,如dict["Tom"];
如果map中不存在访问的该key,那么就会自动创建该key并且设置默认初值。 - 修改也是直接进行修改:
dict["Tom"] = 4;
判断key是否存在
使用表达式 映射名.count(key)
,如果存在返回1;否则返回0.
遍历映射
- 使用
map<key,value>::iterator it;
定义一个迭代器。 - 定义迭代器可以直接使用
auto it;
编译器自动判断。 - 这里迭代器指向的元素是一对键值pair,有
first
和second
两个成员变量,分别代表key
和value
。 - 打印的时候还是使用解引用
(*it).first
或者(*it).second
等价于it->first
或者it->secnd
for(map<string,int>::iterator it = dict,begin(); it != dict.end(); it++)
{
cout << it->first << "->" it->second << " ";
}
获取键值pair个数
使用 映射名.size()
清空map数据
使用 映射名.clear();
清空数据同时释放map
占用的内存
更多应用
除了基本数据,使用map还可以map套map,map套set
map<int,set<string> > M1;
map<int,map<string,int> > M2;
代码示例
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main()
{
map<string,int> Class;
int num = Class.size();
cout << "There are " << num << "pair:" << endl;
for(map<string,int>::iterator it = Class.begin(); it != Class.end(); it++)
{
cout << it->first << "->" << it->second << " ";
}
cout << endl;
Class.insert(make_pair("张飞",1));
Class["小航"] = 3;
num = Class.size();
cout << "There are " << num << "pair:" << endl;
for(map<string,int>::iterator it = Class.begin(); it != Class.end(); it++)
{
cout << it->first << "->" << it->second << " ";
}
return 0;
}
//输出:
There are 0pair:
There are 2pair:
小航->3 张飞->1
5.#include<stack>
栈
定义
使用stack<数据类型> 栈名;
进栈和出栈
使用栈名.push(新元素)
入栈
栈名.pop()
出栈并且返回栈顶元素
访问栈顶元素
使用栈名.top()
返回栈顶元素
查看大小
使用栈名.size()
返回大小
判空
使用栈名.empty()
表达式返回bool值
注意<stack>
容器没有.clear()
成员函数!!
完全可以使用vector来代替stack,vector更加灵活
6.#include<queue>
队列
定义
使用queue<数据类型> 队列名;
进队和出队
使用队名.push(新元素)
入队
队名.pop()
出对并且返回队首元素
访问队首队尾
使用队名.front()
队名.back()
查看大小
使用队名.size()
返回大小
判空
使用队名.empty()
表达式返回bool值
注意<stack>
容器没有.clear()
成员函数!!
6.C++11标准auto关键字
- 以下三种写法是等效的:
//1
for(map<string,int>::iterator it = M1.begin(); it != M1.end(); it++)
{
cout << it->first << "->" << it->second << " ";
}
//2
for(auto it = M1.begin(); it != M1.end(); it++)
{
cout << it->first << "->" << it->second << " ";
}
//3
for(auto &pair : M1)
{
cout << pair.first << "->" << pair.second << " ";
}
前两种it->first
其实和(*it).first
是等效的;第三种是引用的用法。
7.#include<string>
字符串
定义
使用string 字符串名(长度,初值);
例如string name(4,'K');
修改
整体修改,直接重新赋值即可name = "Marry";
细节修改,name[1] = 'u';
运算符
+:连接字符串
=:赋值
==:判断俩个字符串是否相同
#include<string>
#include<iostream>
using namespace std;
int main()
{
string s;
cin >> s;
cout <<s << endl;
}
成员函数
使用 .size()
函数获取字符串的长度