This is just a test, for personal study.
iostream
exit(0); //终止程序
1.字符串元素统计
//c++风格字符串
string a = "ab c\0de";
cout << a.size() << endl; //=4 统计到\0(或输入按回车)
cout << a.length() << endl; //=4 统计到\0(或输入按回车)
//c语言风格字符串
char s[999] = "ab c\0de";
cout << strlen(s); //=4
2.连续输入
以回车停止
int arr[1005];
do { cin >> arr[i];i++; } while (cin.get() != '\n'); //用do..while否则会吞输第一个输入的字符
以EOF停止
//c++
int n;
while (cin >>n) {cout << n << endl; } //以EOF结束
//c语言
int n;
while(scanf("%d",&n) != EOF) { printf("%d",n);} //以EOF结束
3.swap
交换两个数的值
int a = 10,b = 20;
swap(a,b);//交换后a = 20, b = 10
string
常用函数
常用函数 | |
---|---|
a.push_back(x); | 在末尾添加一个元素x |
a.pop_back(x); | 删除末尾元素x |
a.insert(pos,x); | 在pos点插入元素x |
a.clear(); | 清空元素 |
a.replace(pos,len,“abc”); | 元素替换 |
a.find(“abc”); | 返回第一次出现目标字符串的位置,没有则返回string::npos(通常定义为-1或无穷大) |
a.find_last_of(“abc”); | 返回最后一次出现目标字符串的位置,没有则返回string::npos(通常定义为-1或无穷大) |
getline(cin,str1,c); | 读取字符,包括空格和回车,遇到c停止 |
str1.compare(str2); | 比较两个字符串的字典序 |
memset(arr,‘c’,sizeof arr); | 初始化char[]型字符串为字符‘c’,或将数组元素初始化为0/-1/0x3f3f3f3f; |
a+=b; | 字符串合并 |
a.size(); a.length(); | 返回字符串元素个数 |
a.empty(); | 返回字符串是否为空 |
count(a.begin(), a.end(), c); | 计数字符c出现的次数 |
a.substr(pos,len); | 返回下标从pos开始长度为len的子串 |
a.c_str(); | 返回这个string对应的字符数组的头指针 |
1.replace字符替换
//a.replace(pos,len,"str"); 从pos位置开始,长度为len,替换为str
string a = "abcdefg";
a.replace(0, 4, "66");//或者用迭代器a.replace(a.begin(), a.begin() + 4, "66");
cout << a;//66efg
//a.replace(pos,len,n,'c'); 从pos位置开始,长度为len,替换为重复n次的字符c
string a = "abcdefg";
a.replace(0,4,3,'6');
//将字符串中的a用b替换
replace(str.begin(), str.end(), 'a', 'b'); //需包含#include <algorithm>
2.to_string数字转字符串
int n = 114514;
string a = to_string(n);
//字符串转数字
string a = "114514";
int n = atoi(a.c_str());//从第一位开始,遇到非数字停止,诺第一位不是数字则为0
2.getline带空格/回车输入字符串
有时需要在使用前加getchar();缓冲,防止吞输入。
string str;
getline(cin,str,c);//读取到字符c则停止,诺参数c不写,则默认读取到回车停止,c可以为('字符') ,(’\n') ,(' ') 等
cout << str;
3.find查找
rfind则为逆向查找,从字符串后面往前查找
当find函数未找到要查找的子字符串时,它将返回常量值string::npos 通常定义为-1;或一个很大的无符号整数类型的值
//查找目标字符串的下标
#include<iostream>
#include<string>
using namespace std;
int main() {
string arr = "komeijikoishi";
string target = "oi";
int index = arr.find(target);//返回第一次出现目标字符串的位置
if(arr.find(target == -1)) cout << "不存在改子串" << endl;
cout << index << endl;
int index2 = arr.find("i", 5); //从下标为5的位置开始查找
cout << index2 << endl;
int index3 = arr.find_first_of("i"); //查找目标字符串第一次出现的位置
cout << index3 << endl;
int index4 = arr.find_last_of("i"); //查找目标字符串最后一次出现的位置
cout << index4 << endl;
return 0;
}
//查找目标字符串出现的中次数
string s, c;
while (cin >> s >> c) {
int index = 0;//用来存储不断更新最新找到的位置
int sum = 0;//累加出现的次数
while ((index = s.find(c,index)) != string::npos) {
cout << "sum: " << sum+1 << " index: " << index <<endl;
index += c.length();//上一次s中与c完全匹配的字符应跳过,不再比较
sum++;
}
cout << sum << endl; // lllllll中ll出现了3次
}
//查找字符串中,某一个字符出现的次数
string a = "abcdefga";
cout << count(a.begin(), a.end(), 'a');
4.compare比较字典序
区分大小写,从头开始依次比较字符对应ASCII码大小
string A = "12345";
string B = "12454";
cout << A.compare(B);
//A>B 返回1; A<B 返回-1; A==B 返回0;
//str_cmp比较char类型字符串的字典序
char A[] = "abc";
char B[] = "abc";
strcmp(A,B)
//A>B 返回1; A<B 返回-1; A==B 返回0;
5.memset初始化
按字节初始化
//char[]型字符串
char arr[100];
memset(arr,'a',sizeof arr);//可以初始化为任意字符
for (int i = 0;i < 100;i++) cout << arr[i];
//非字符型数组
int arr[100];//按字节初始化,int为4字节
memset(arr, -1, sizeof arr);//初始化为-1或0或0x3f
//-1 = (1111 1111 1111 1111) = -1
//0 = (0000 0000 0000 0000) = 0
//0x3f=(3f 3f 3f 3f) = 0x3f3f3f3f
for (int i = 0;i < 100;i++) cout << arr[i];
cmath
常用函数
常用函数 | |
---|---|
pow(a,b) | a^b次方 |
sqrt(a),sqrtl(a),sqrtf(a); | sqrt开平方根(整型,long double,float)//cbrt开立方 |
abs,fabs; | 绝对值(整型,浮点型) |
ceil(n);floor(n); | 向上取整;向下取整 |
round(n); | 四舍五入到整数 |
c语言为math.h
1.指数
n * pow(a,b); //相当于n*(a^b)
//pow参数类型和返回值类型均为浮点型,注意以下情况会导致输出与预期不符而wrong answer
int a = 1234;
cout << a*a << endl;//1522756
cout << pow(a, 2)<< endl;//1.52276e+06
2.开方根
sqrt(n); //开平方根
sqrtl(n); //高精度,参数类型是long double;防止long long类型强转为double的误差
cbrt(n); //开三次方
pow(n,1.0/m);//开n次方(1.0/m或1/m.0)
3.绝对值
abs(n); //整型
fabs(n); //浮点型
4.取整
ceil(n); //向上取整 ceil(1.5) = 2;
//无camth头文件,两个整型的商向上取整:int n = a/b + bool(a%b)
floor(n); //向下取整 floor(1.5) = 1;
5.四舍五入
round(n); //四舍五入到整数
round(n*100)/100; //四舍五入保留2位小数
algorithm
常用函数
常用函数 | |
---|---|
sort(begin,end,cmp) | 排序 |
is_sorted(begin,end) | 返回所给序列是否已按升序排列 |
lower_bound(begin,end,value) | 返回第一个>=v值的地址(-begin即为下标) |
upper_bound(begin,end,value) | 返回一个>v值的地址(-begin即为下标) |
count(begin,end,value) | 计数v值出现了多少次 |
count_if(begin,end,cmp) | 按自定义cmp规则计数 |
reverse(begin,end) | 翻转所在区间数值 |
find(begin,end,value) - begin | v值第一次出现的下标,没有则返回元素末尾下标+1 |
erase(begin,end) | 删除范围内元素 |
unique(begin,end) | [移除范围内的连续重复元素 ,返回去重之后的尾地址(使用前先排序)][实际并没有删除,只是将重复元素放到容器末尾,不改变容器大小] |
next_permutation(begin,end) | 将元素排列为下一个字典序,没有下一个则返回0 |
prev_permutation(begin,end) | 将元素排列为上一个字典序,没有上一个则返回0 |
max_element(begin,end) | 返回所给范围内最大值的地址 |
min_element(begin,end) | 返回所给范围内最小值的地址 |
1.sort排序
语法:sort(begin, end, cmp);
其中begin为指向待sort()的数组的
第一个元素的指针
,end为指向待sort()的数组的最后一个元素的下一个位置的指针
,cmp参数为排序准则(不写的话,默认从小到大进行排序);时间复杂度:n*log2(n)
//从小到大
sort(arr, arr+10);
sort(str.begin(),str.end());
//从大到小则cmp = greater<int>()
sort(arr, arr+10, greater<int>());
sort(str.begin(),str.end(),greater<int>());
自定义cmp排序准则
//结构体排序
#include <iostream>
#include <algorithm>
using namespace std;
struct hero{ string name;int sco; };
void info(hero arr[], int len){
string nameSeed[5] = {"小毛","小刘","小李","小张","小王"};
for (int i = 0;i < len; i++) {
arr[i].name += nameSeed[i];
cout << "姓名:" << arr[i].name;
cout << "\t请输入分数:";cin >> arr[i].sco;
}
}
bool agerank(hero a, hero b) { return a.sco > b.sco; }//自定义排序
void printInfo(hero arr[],int len) {
cout << "\n\n\n排序后\n" << endl;
for (int i = 0;i < len;i++) {
cout << "姓名:" << arr[i].name << "\t分数:" << arr[i].sco << endl;
}
}
int main() {
hero arr[5];
int len = sizeof(arr) / sizeof(arr[0]);
info(arr, len);//1.输入信息
sort(arr, arr+len,agerank);//2.排序
printInfo(arr, len);//3.输出
}
2.reverse翻转
reverse(str.begin(), str.end()); //字符串倒序
reverse(a,a+n); //数组的翻转,n为数组元素个数
3.unique
[移除范围内的连续重复元素 ,返回去重之后的尾地址(使用前先排序)][实际并没有删除,只是将重复元素放到容器末尾,不改变容器大小]
unique(alls.begin(), alls.end());
//去重
erase(unique(v.begin(),v.end()),v.end());
4.count
在序列中统计某个值出现的次数
cout<<count(arr.begin() , arr.end() , searchValue) << endl;
#include <iostream>
using namespace std;
int main() {
int n,x,arr[100]; cin >> n>>x;
for (int i = 0;i < n;i++)
cin >> arr[i];
cout << count(arr,arr+n,x);
}
count_if
返回满足条件范围内的元素个数
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector <int> myvector;
bool isEven(int elem){ return elem % 2 == 0;}
bool cmp(int elem) { return elem > 2; }
void main(){
for (int i = 0;i < 9;i++){
myvector.push_back(i+1);
cout << myvector[i];
}
// 计算偶数个数
int ctif = count_if(myvector.begin(), myvector.end(), isEven);
// 计算大于2的个数
int ctg = count_if(myvector.begin(), myvector.end(), cmp);
cout << "偶数元素个数:" << ctif << endl;
cout << "超过2的元素个数: " << ctg << endl;
}
5.lower_bound
使用时需要对数组先进行排序,时间复杂度为O(logN);
lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,得到找到数字在数组中的下标。
#include<bits/stdc++.h>
using namespace std;
const int maxn=100000+10;
const int INF=2*int(1e9)+10;
#define LL long long
int cmd(int a,int b){
return a>b;
}
int main(){
int num[6]={1,2,4,7,15,34};
sort(num,num+6); //按从小到大排序
int pos1=lower_bound(num,num+6,7)-num; //返回数组中第一个大于或等于被查数的值
int pos2=upper_bound(num,num+6,7)-num; //返回数组中第一个大于被查数的值
cout<<pos1<<" "<<num[pos1]<<endl;
cout<<pos2<<" "<<num[pos2]<<endl;
sort(num,num+6,cmd); //按从大到小排序
int pos3=lower_bound(num,num+6,7,greater<int>())-num; //返回数组中第一个小于或等于被查数的值
int pos4=upper_bound(num,num+6,7,greater<int>())-num; //返回数组中第一个小于被查数的值
cout<<pos3<<" "<<num[pos3]<<endl;
cout<<pos4<<" "<<num[pos4]<<endl;
return 0;
}
例题:https://www.luogu.com.cn/problem/P2249
#include<iostream>
using namespace std;
int a[1000005];
int main() {
int n, m;
scanf("%d%d", &n, &m);
for(int i = 1; i<=n; i++) {
scanf("%d", &a[i]);
}
while(m--) {
int x;
scanf("%d", &x);
//手动实现:
// int l = 1, r = n;
// while(l != r) {
// int mid = (l+r)/2;
// if(a[mid]>=x) r = mid;
// else l = mid+1;
// }
//函数实现
int tot = lower_bound(a+1, a+n+1, x) - a;//返回第一个大于等于x的位置
int ans = upper_bound(a+1, a+n+1, x) - a;//返回第一个大于x的位置
printf("%d\n", tot);
}
return 0;
}
6.next_permutation
prev_permutation求当前排列的上一个排列
求当前排列的下一个排列,当当前序列不存在下一个排列时,函数返回false,否则返回true。
//全排列需要先对数组按升序排序
int arr[100];
int n; cin >> n;
for (int i = 0;i < n;i++)
cin >> arr[i];
sort(arr, arr + n);
do {for (int i = 0; i < n; i++){
cout << arr[i] << ' ';
}cout << endl;
}
while (next_permutation(arr, arr + n));
//prev_permutation求当前排列的上一个排列
string a = "cadb";
sort(a.begin(), a.end(),greater<int>());
do {cout << a << endl;
} while (prev_permutation(a.begin(), a.end()));
iomanip
常用函数
常用函数 | |
---|---|
fixed | 以浮点数形式输出 |
setprecision(n) | 保留n位小数 |
setw(n) | 设置位宽为n |
setfill© | 以字符c填充位宽空位 |
left right | 左/右对齐 |
1.浮点数精度
setprecision()
//超过对应数据类型范围仍然会掉精度
double n = 1.145141919810;
cout <<fixed << setprecision(6) << n << endl;
//将a四舍五入到n位,不足n位则会自动添0(如果n为整型,n*1.0即可)
cout << 1.1 << endl;//会对后续其它浮点数输出会造成影响
cout << defaultfloat << 1.1 << endl;//defaultfloat可以取消改影响
cout << 1.1 << endl;
double a = 1.1234567;
a = (int)(1000.0 * a + 0.5) / 1000.0;//保留3位小数,四舍五入,根据需要增删0
//c语言自定义保留n位小数,四舍五入
#include<stdio.h>
int main(){
int n;
scanf("%d",&n);
printf("%.*f",n,123.666666);
}
2.位宽
setw() 默认右对齐
int a = 1, b = 12, c = 123;
cout << setw(4) << a << endl;
cout << setw(4) << b << endl;
cout << setw(4) << c << endl;
3.字符填充
setfill(c ) //以字符c填充空位
string s = "abcde";
cout << setfill('*') <<setw(10)<< s << endl;
4.对齐
left //输出左对齐
right //输出右对齐
for (int i = 0;i <5;i++){
cout << setw(5) << left << i;
}
map
常用函数
常用函数 | |
---|---|
m.begin() | 返回指向map头部的迭代器 |
m.end() | 返回指向map末尾的迭代器 |
m.insert({x,y}) | 插入元素(pair类型) |
m.clear() | 删除所有元素 |
m.size() | 返回map中元素的个数 |
swap(m1,m2) | 交换两个map容器的所有元素 |
m.empty() | 返回容器是否为空 |
erase() | 参数为一个迭代器或键值则删除该元素,参数为两个迭代器时则删除两个迭代器之间的元素 |
m.find(x) | 返回键值为x的元素的迭代器 |
lower_bound(x) | 返回一个迭代器,指向键值 >= x 的第一个元素 |
upper_bound() | 返回一个迭代器,指向键值 > x 的第一个元素 |
1.定义
map<type1name,type2name> m1;//第一个是关键字key(每个关键字只能出现一次)的类型,第二个是对应的值value的类型
multimap<type1name,type2name> m2;可以有多个相同的键值对
插入元素
map<int, string> student;
//1.用insert函数插入pair数据
student.insert(pair<int, string>(000, "student_zero"));
//2.用insert函数插入value_type数据
student.insert(map<int, string>::value_type(001, "student_one"));
//3.用"array"方式插入
mapStudent[1] = "student_first";
mapStudent[2] = "student_second";
2.访问元素
//通过键值 //时间复杂度为logN
#include <iostream>
#include <map>
using namespace std;
map<string,int>student;
int main() {
int n; cin >> n;
for (int i = 0; i < n; i++){
string name; int num;
cin >> name >> num;
student[name] = num;
}
//输入姓名 查找学号
string find_name; cin >> find_name;
cout << student[find_name] << endl;
return 0;
}
//通过迭代器 map<string, int>::iterator it = student.begin();
#include <iostream>
#include <map>
using namespace std;
map<string,int>student;
int main() {
int n; cin >> n;
for (int i = 0; i < n; i++){
string name; int num;
cin >> name >> num;
student[name] = num;
}
//遍历姓名及其学号
for (map<string, int>::iterator it = student.begin(); it != student.end(); it++)
cout << it->first << " " << it->second << endl;
}
3.例
https://www.luogu.com.cn/problem/P2249
#include <iostream>
#include <map>
using namespace std;
map<int, int> k; //1.创建映射关系int > int
int num[1000006];
int main() {
int n, m; cin >> n >> m;
for (int i = 1; i <= n; i++) {
scanf("%d", &num[i]);
if (num[i] != num[i - 1]) k[num[i]] = i; //2.输入
}
for (int i = 0;i < m;i++){
int a; scanf("%d", &a);
if (!a) printf("1 ");
else if (k.count(a)) printf("%d ", k[a]); //3.输出
else printf("-1 ");
}
return 0;
}
vector
向量(Vector)是一个封装了动态大小数组的顺序容器(Sequence Container)。跟任意其它类型容器一样,它能够存放各种类型的对象。可以简单的认为,向量是一个能够存放任意类型的动态数组。
常用函数
常用函数 | |
---|---|
v.front() | 返回第一个元素 |
v.back() | 返回最后一个元素 |
v.push_baack() | 向容器末添加一个元素 |
v.pop_back() | 删除容器末的元素 |
insert() | 向容器中插入元素 |
v.size() | 返回容器内元素个数 |
v.empty() | 返回容器是否为空 |
v.clear() | 清空容器 |
v1.compare(v2) | 比较容器v1和v2 |
v1.swap(v2) | 交换两个容器,vector特化版的swap |
//支持两个容器比较 按字典序比较
vector<int>a{1,3,3,4};
vector<int>b{1,2,16,5,5};
cout << (a > b) << endl;
1.定义及初始化
//定义一个空的容器
vector<int>v1;
//定义一个空的vector类型数组
vector<int>arr[100];
//定义一个含有10个元素的容器
vector<int>v2(10); //int类型默认初始化为0
//定义一个含有10个元素的容器,并将其初始化
vector<string>v3(10,"abc");
2.增删特定位置元素
A.push_back(x) ;//在末尾添加元素x
A.pop_back();//删除末尾元素
A.insert(A.begin(),x);//在开头添加元素x
A.erase(A.begin());//删除开头元素
A.clear(); //清空所有元素
//通过迭代器:
//insert(po,x) 在po位置插入元素x
vector<int> A = { 100,200,300,400,500,600 };
vector<int>::iterator it; //通过迭代器访问容器
it = A.begin();
A.insert(it, 111); //向索引为0的位置插入元素111
//输出内容为:111 100 200 300 400 500 600
for (int i = 0; i < A.size(); i++) {
cout << A[i] << " ";
}
cout << endl;
it = A.begin() + 2;
A.insert(it, 222); //向索引为2的位置插入元素222
//输出内容为:111 100 222 200 300 400 500 600
for (int i = 0; i < A.size(); i++) {
cout << A[i] << " ";
}
cout << endl;
it = A.end();
A.insert(it, 999); //向A的末尾插入元素999
//输出内容为:111 100 222 200 300 400 500 600 999
for (int i = 0; i < A.size(); i++) {
cout << A[i] << " ";
}
cout << endl;
//erase() 函数来删除指定位置的元素
vector<int> A = { 100,200,300,400,500,600 };
vector<int>::iterator it;
it = A.begin(); //索引为0的位置
A.erase(it); //删除索引为0的位置的元素
//输出内容为:200 300 400 500 600
for (int i = 0; i < A.size(); i++) {
cout << A[i] << " ";
}
cout << endl;
it = A.begin() + 2; //索引为2的位置
A.erase(it); //删除索引为2的位置的元素
//输出内容为:200 300 500 600
for (int i = 0; i < A.size(); i++) {
cout << A[i] << " ";
}
cout << endl;
3.删除指定数值元素
//如果能在目标vector中找到该数值的元素,直接删除
//如果目标vector中找不到该数值的元素,不做任何操作,不会报错
vector<int> A = { 100,200,300,400,500,600 };
A.erase(remove(A.begin(), A.end(), 500), A.end()); //删除数值为500的元素
A.erase(remove(A.begin(), A.end(), 700), A.end()); //删除数值为700的元素
//输出内容为:100 200 300 400 600
for (int i = 0; i < A.size(); i++) {
cout << A[i] << " ";
}
cout << endl;
//排序再去重
sort(alls.begin(), alls.end());
alls.erase(unique(alls.begin(), alls.end()), alls.end());
//unique把所有重复元素放到容器后面,再把不重复元素提前,返回最后一个不重复元素位置(algorithm)
//erase删除最后一个不重复元素位置到数组末尾的位置的所有元素(vector)
4.查找指定数值的元素
//使用 find() 函数查找 函数的返回值为迭代器或指针
vector<int> myVector = { 100,200,300,400,500,600 };
vector<int>::iterator it = find(myVector.begin(), myVector.end(), 500);
//输出内容为:目标元素的索引为: 4
if (it != myVector.end()) {
cout << "目标元素的索引为: " << distance(myVector.begin(), it) <<endl;
}
else {
cout << "没有找到" <<endl;
}
5.遍历元素
vector v = { 100,200,300,400,500,600 };
//通过迭代器
for (vector<int>::iterator i2 = v.begin(); i2 != v.end();i2++) {
cout << *i2 << endl;//*i2解引用
}
//或者这里直接使用auto,不需要根据myVector中元素的类型改变,自动推断变量类型
for (auto it : v) {
cout << it << " ";
}
//通过下标
for (int i = 0;i < v.size();i++){
cout << v[i] << " ";
}
6.动态二维数组
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
vector<vector<int>>v;//V = {v1,v2,v3...}
int main() {
//构建一个arr[n][m];的动态二维数组
int n, m; cin >> n >> m;
for (int i = 0; i < n;i++) {
vector<int>v1;
for (int j = 0; j < m;j++) {
int temp; cin >> temp;
v1.push_back(temp);
}
v.push_back(v1);
}
v[1].pop_back();
sort(v.begin(), v.end());//排序,比较字典序v1,v2,v3...
for (int i = 0; i < v.size();i++) {
for (int j = 0; j < v[i].size(); j++) {
cout << v[i][j] << ' ';
}puts("");
}
}
queue
队列是一种先进先出(FIFO)的数据结构,元素按照其被添加的顺序进行处理。
常用函数
常用函数 | |
---|---|
q.push(x) | 在队尾插入元素x |
q.pop(x) | 删除队首元素 |
q.size() | 返回队列中元素个数 |
q.empty() | 返回队列是否为空 |
q.front() | 返回队首元素 |
q.back() | 返回队尾元素 |
1.定义及初始化
queue<Type, Container> // (<数据类型,容器类型>)
初始化时必须要有数据类型,容器可省略,省略时则默认为deque 类型
//queue的定义 例
queue<int>q1; //定义一个储存数据类型为int的queue容器q1
queue<double>q2; //定义一个储存数据类型为double的queue容器q2
queue<string>q3; //定义一个储存数据类型为string的queue容器q3
queue<结构体类型>q4; //定义一个储存数据类型为结构体类型的queue容器q4
2.清空
queue没有clear()函数;可以通过以下方式清空队列
queue<int>q;
q = queue<int>();
3.元素访问
queue队列的元素只能访问队首元素或队尾元素,通过.pop()每次将队首元素弹出后遍历队列
queue<int>q;
for (int i = 0; i < 10;i++) {
q.push(i*10);
}
for (int i = 0; i < 5;i++) {
cout << q.front() << ' ';
q.pop();
}
4.优先队列
每次元素入队后会按一定次序排列元素,无法访问队尾元素,默认大根堆
常用函数 | |
---|---|
pq.push(x) | 向队列插入元素x |
pq.pop() | 弹出队首元素 |
pq.top() | 返回队首元素 |
pq.size() | 返回队列元素个数 |
pq.empty() | 返回队列是否为空 |
priority_queue<结构类型> 队列名;
priority_queueq0;
priority_queue<int,vector,less >q1; //大根堆,父节点>子节点
priority_queue<int, vector, greater> q2; //小根堆 ,父节点<子节点
//例 利用大根堆实现元素自动从大到小排列
#include <iostream>
#include <queue>
using namespace std;
priority_queue<int>q;
int main() {
for (int i = 0;i < 5;i++){
int x; cin >> x;
q.push(x);
}
while (q.size()){
cout << q.top();
q.pop();
}
return 0;
}
deque
双端队列容器,速度慢
常用函数
常用函数 | |
---|---|
front() | 返回第一个元素的引用。 |
back() | 返回最后一个元素的引用。 |
assign() | 用新元素替换原有内容。 |
push_back() | 在序列的尾部添加一个元素。 |
push_front() | 在序列的头部添加一个元素。 |
pop_back() | 移除容器尾部的元素。 |
pop_front() | 移除容器头部的元素。 |
insert() | 在指定的位置插入一个或多个元素。 |
erase() | 移除一个元素或一段元素。 |
clear() | 移出所有的元素,容器大小变为 0。 |
swap() | 交换两个容器的所有元素。 |
emplace() | 在指定的位置直接生成一个元素。 |
emplace_front() | 在容器头部生成一个元素。和 push_front() 的区别是,该函数直接在容器头部构造元素,省去了复制移动元素的过程。 |
emplace_back() | 在容器尾部生成一个元素。和 push_back() 的区别是,该函数直接在容器尾部构造元素,省去了复制移动元素的过程。 |
定义及初始化
//1) 创建一个没有任何元素的空 deque 容器:
deque<int>d1;
//)2 创建一个具有 10 个元素的 deque 容器,其中每个元素都采用对应类型的默认值:
deque<int>d2(10,-1); //int类型初始化为-1,第二个参数不填则默认为0
//)3 创建一个具有 10 个元素的 deque 容器,并为其初始化
deque<string>d3(10,"abc");
//)4 拷贝构建
deque<int> d4(d1);
stack
栈,先进后出
常用函数
常用函数 | |
---|---|
a.push() | 插入一个元素 |
a.pop() | 弹出栈顶元素 |
a.top() | 返回栈顶元素 |
a.size() | 返回元素个数 |
a.empty() | 返回栈中元素是否为空 |
例
#include <iostream>
#include <stack>
using namespace std;
stack<int>p;
int main() {
for (int i = 0; i < 5;i++) {
int x; cin >> x;//1 2 3 4 5
p.push(x);
}
for (int i = 0; i < 5;i++) {
cout << p.top();//54321
p.pop();
}
return 0;
}
set
set/multiset是以rb_tree为底层机构,因此有元素自动排序的特性。元素不能直接被改变
set 不可存在重复的数
multiset 可以存在重复的数
常用函数
常用函数 | |
---|---|
insert() | 插入一个数 |
find() | 查找一个数 |
count() | 返回一个数的个数 |
erase() | 根据参数,删除一个数/一个迭代器/两个迭代器a到b之间的值 |
empty() | 判断容器是否为空 |
size() | 返回当前容器元素个数 |
clear() | 删除容器中所有元素 |
begin() | 返回指向容器第一个元素的迭代器 |
end() | 返回指向容器末尾元素的迭代器 |
lower_bound() | 返回第一个大于等于n的迭代器 |
upper_bound() | 返回第一个大于n的迭代器 |
equal_range() | 返回元素值为n的区间(pair类型) //*a.equal_range().first和 *a.equal_range()second之间 |
例
#include <iostream>
#include <set>
using namespace std;
set<int>p;
int main() {
for (int i = 0; i < 5;i++) {
int x; cin >> x;
p.insert(x);
}
/*cout << *p.lower_bound(2) << endl;
cout << *p.upper_bound(2) << endl;*/
cout << *p.equal_range(2).first;
cout << *p.equal_range(2).second;
for (auto it= p.begin();it != p.end();it++) {//通过迭代器遍历
cout << *it << endl;//*号解引用
}
p.erase(p.begin(), p.end());
return 0;
}
bitset
-
每位只占1bite空间,支持各种位运算如
- | & ^ << >> [ ] == != 等
常用函数
常用函数 | |
---|---|
size() | 返回长度 |
count() | 返回位值为1的数量 |
set() | 无参则将所有位设为1,一个参数则将下标为pos设为1,两个参数则将将下标为pos的位设为k |
reset() | 无参将所有位设为0,一个参数则将下标为pos的位设为0 |
flips() | 无参则将所有位取反,一个参数则将下标为pos的位取反 |
all() | 是否所有位都是1 |
none() | 是否所有位都是0 |
any() | 是否至少有一个1 |
to_string() | 返回为字符串型; string str = a.to_string(); |
初始化
bitset<N> bitset1; // 创建一个长度为 N 的 bitset,所有位都被初始化为 0
bitset<N> bitset2(value); // 使用二进制整数 value 初始化一个长度为 N 的 bitset //无符号整数
bitset<N> bitset3(string); // 使用二进制字符串 string 初始化一个长度为 N 的 bitset//只含'0'或'1'
bitset<N> bitset4(bitset); // 使用另一个 bitset 初始化一个长度为 N 的 bitset
ctmie
1.clock_t
//计算程序运行某一段的耗时(ms)
#include <iostream>
#include <ctime>
using namespace std;
clock_t start1, end1, start2, end2;
int main() {
start1 = clock();
for (int i = 0; i < 5e8; i++){
int b; b = i;
}
end1 = clock() - start1;
cout << end1 << "ms" << endl;
start2 = clock();
for (int i = 0; i < 1e9; i++){
int b; b = i;
}
end2 = clock();
cout << end2 - start2 << "ms" << endl;
}
//或者这样写
#include <iostream>
using namespace std;
int main() {
int start1 = clock();
for (int i = 0; i < 1e7; i++);
int end1 = clock();
cout << end1 - start1 << "ms" << endl;
int start2 = clock();
for (int i = 0; i < 1e9; i++);
int end2 = clock();
cout << end2 - start2 << "ms" << endl;
return 0;
}