哈希表的常用函数
#include<iostream>
#include<unordered_map>
#include<string>
int main(){
//创建一个unordered_map实例
std::unordered_map<std::string,int>hash_table;
//插入数据
hash_table["one"]=1;
int key="one";
if(hash_table.find(key)!=hash_table.end()){//当find没有找到对应值时,会返回一个end
std::cout<<"找到键为"<<key<<"的元素,值为"<<hash_table[key]<<std::endl;
}
//遍历哈希表
for(const auto& pair:hash_table){
std::cout<<"键:"<<pair.first<<"值为"<<pair.second<<std::endl;
}
//删除元素
hash_table.erase("one");
return 0;
}
vector几种删除元素的方法
vector是一个非常灵活且功能强大的序列容器
:
1.使用erase成员函数删除单个元素
erase函数可以接受一个迭代器参数,指向要删除的元素。调用erase后,
它会移除指定位置的元素,并返回下一个元素的迭代器
vector<int>v={1,2,3,4,5};
auto it=find(v.begin(),v.end(),3);
if(it!=v.end()){
v.erase(it);//删除元素3
}
2.使用erase成员函数删除指定范围的元素
erase函数可以接受两个迭代器作为参数,删除一个范围内的元素。
这两个迭代器应该形成一个有效的区间,表示要删除的元素范围
vector<int> v={1,2,3,4,5,6};
v.erase(v.begin()+2,v.begin()+4);//删除元素3和4
3.使用clear成员函数删除所有元素
vector容量保持不变
v.clear();
4.使用swap和析构函数删除元素
如果你想删除一个vector中的特定元素,但又不想改变其它元素的顺序,
可以使用swap函数将该元素vector的最后一个元素交换,然后删除最后一个元素
vector<int>v={1,2,3,4,5};
swap(v[2],v.back());//将元素3与最后一个元素5交换
v.pop_back(); //删除原最后一个元素,即原来的3
5.使用remove和erase成员函数删除满足特定条件的元素
remove函数可以将满足特定条件的元素移动到vector末尾,并返回一个指向新逻辑末尾的迭代器,
然后,你可以使用erase函数删除这些元素
vector<int>v={1,2,3,4,5,3};
auto newEnd=remove(v.begin(),v.end(),3);//将所有元素3移动到末尾
v.erase(newEnd,v.end());//删除所有元素3
使用at()函数安全的访问元素
v.erase(v.begin() + indexToDelete);//v.begin()为迭代器起点,indexToDelete为要删除元素的下标
STL
//快速排序
//sort(arr.begin(),arr.end());
//向量vector
//vector<类型>arr(长度,[初值])
#include<bits/stdc++.h>
using namespace std;
int main(){
vector<int>arr;//一维,长度是可变的
vector<vector<int> >dp(5,vector<int> (6,10));//二维数组,5行6列,初值为10
vector<vector<vector<int> > >dp2(5,vector<vector<int> >(6,vector<int>(4)));//三维
int mat[5][6][4]; //二者等价
arr.push_back(1);//在后面添加一个元素
/*for(auto &e : arr){//arr给的是地址,因此需要&,auto自动改变相应类型
cout<<e<<endl;
} */
arr.pop_back();//删除后面一个元素
arr.clear();//清空vector中的所有元素
if(arr.empty()){//判断是否为空
cout<<"为空";
}
arr.resize(5,3);//重新设置vector的长度,和初值(默认值),(长度,初值)
//vector从在于对空间不会爆栈
//能提前声名长度,应直接声明长度,节省时间
arr.size();//得到vector的长度
//size()返回的类型是size_t,size_t的大小与编译器有关
return 0;
}
stack栈
#include<bits/stdc++.h>
using namespace std;
int main(){
stack<double>stk;
stk.push(1.0);//入栈
stk.push(2.0);
cout<<stk.top()<<endl;//top()输出栈顶元素
stk.pop();//出栈
cout<<stk.top()<<endl;
//stack与vector很相似,可以将vector当作栈使用
vector<double> vec;
vec.push_back(1.0);
vec.push_back(2.0);
cout<<vec.back()<<endl;
vec.pop_back();
return 0;
}
queue队列
#include<bits/stdc++.h>
using namespace std;
int main(){
queue<int> que;
que.push(1)//入队;
que.push(2);
cout<<que.front()<<endl;//队首
que.pop(); //出队
cout<<que.back()<<endl;//队尾
cout<<que.size()<<endl;//队长
cout<<que.empty()<<endl;//是否为空
return 0;
}
//优先队列priority_queue
//二叉堆来实现
//每次从队列中取出大小最大/最小的元素
//只能访问堆顶
#include<bits/stdc++.h>
using namespace std;
int main(){
priority_queue<int> pque;
pque.push(1);//入堆
pque.push(2);
cout<<pque.top()<<endl;//输出堆顶
pque.pop();//出堆
priority_queue<int,vector<int>,greater<int>>pque;//小顶堆如果需要long long就把int该为long long
return 0;
}
集合set
//确定性,互异性,无序性
//set有确定性,互异性
//multiset有确定性
//unordered_set有确定性,互异性,无序性
#include<bits/stdc++.h>
using namespace std;
int main(){
set<int> st;
st.insert(1);//插入元素
st.insert(1);//set含有互异性,不能存入两个1
st.insert(2);
st.erase(2);//删除元素
if(st.find(1)!=st.end()){//如果没找到,find()会等于end()
cout<<"yes"<<endl;
}
cout<<st.size()<<endl;//查大小
cout<<st.empty()<<endl;//判空
for(auto &e:st){
cout<<e<<endl;
}
//可以使用迭代器来进行遍历
for(set<int>::iterator it=st.begin();it!=st.end();it++){//迭代器与地址相似,不过移动的是一个类型的长度
cout<<*it<<endl;
}
return 0;
}
//bool vis[100]如果出现了vis就记为true
//当数组大小【-10^18 ~ 10^18】,元素数量10^6,vis数组无法实现,通过set可以实现
set<int> st;
st.insert(1);
st.insert(2);
if(st.count(1)){//如果set里有这个元素count()返回true
cout<<"yes"<<endl;
}
//set元素只读
映射map
//互异性,无序性
//map含有互异性
//multimap什么都不含
//unordered_map含有互异性,无序性
#include<bits/stdc++.h>
using namespace std;
int main(){
map<int,int> mp;
mp[2]=1;//赋值key,vlaue
cout<<mp[2]<<endl;//输出value
if(mp.find(2)!=end()){//是否找到元素key为2的映射
cout<<"yes"<<endl;
}
mp.erase(2);//消除key为2的映射
cout<<mp.count(2)<<endl;//key为2的映射含有几个
//clear(),size(),empty()
for(map<int>::iterator it=map.begin();it!=mp.end();it++){
cout<<it->first<<' '<<it->second<<endl;
}
for(auto &pr:mp){
cout<<pr.first<<' '<<pr.second<<endl;
}
//记录每个单词的数量
map<string,int>mp;
vector<string> word;
word.push_back("awa");
word.push_back("awa");
word.push_back("awa");
word.push_back("awa");
for(int i=0;i<word.sieze();i++){
mp[word[i]]++;
}
for(auto &pr:mp){
cout<<pr->first<<" "<<pr->second<<endl;
}
//[]访问一个不存在的键的时候,会默认创建这个键,并赋初值为0
return 0;
}
字符串string
#include<bits/stdc++.h>
using namespace std;
int main(){
string s;
char buf[100];
scanf("%s",&buf);//c输入字符串,不需要&,但也不错
s=buf;
printf("%s",s.c_str()); //c语言输出
cout<<buf;//c++输出
string b(100,'0');
b="awa";
cout<<b<<endl;
b+='a';//字符串拼接
cout<<a+b<<endl;
cout<<b.substr(1)<<endl;//从下标为1到末尾的子串
if(b.find("312"!=string::npos)){//如果找不到子串,就会返回npos这个值
cout<<"yes"<<endl;
}
int x=stoi(b);//字符串转为整形
long long x=stoll(b);
float x=stof(b);
double x=stod(b);
long double stold(b);
string b=to_string(x);
return 0;
}
//substr(起点下标,子串长度);
//find()使用暴力实现的
二元组pair
#include<bits/stdc++>
using namespace std;
int main(){
pair<int,int> p1=make_pair(1,2);
pair<char,int> p2={'a',2};
pair<pair<int,char>,char> p3;
}
迭代器iterator
//迭代器
for(vector<int>::iterator it=a.begin();it!=a.end();++it){
cout<<*it<<endl;
} //正向输出
for(vector<int>::iterator it=a.rbegin();it!=a.rend();++it){
cout<<*it<<endl;
}//反向输出
begin()//头迭代器
end()//尾迭代器
rbegin()//反向头迭代器
rend()//反向尾迭代器
迭代器+整形,迭代器向后移动
迭代器-整形,迭代器向前移动
迭代器++,将迭代器向后移动1位
迭代器--,将迭代器向前移动一位
迭代器-迭代器,两个迭代器的距离
prev(it),it的前一个迭代器
next(it),it的后一个迭代器
.end(),.rend()指向的位置是无意义的值,是不可访问的,如a[10]数组的下标位10的元素
迭代器有正向,反向,双向,每个容器的迭代器支持的运算符也可能不同
vector<int>a{1,2,3,4};
for(auto it=a.begin();it!=a.end();it++){
if(*it==2||*it==3){
a.erase(it);
}
}//最后3没删掉,因为当删掉2时迭代器自动就变为了3的位置,然后再it++就跳过去了
for(auto it=a.begin();it!=a.end();it++){
if(*it==4){
a.erase(it);
}
} //但删除4后,迭代器变为end(),it++后就越界了
一些常用算法和数学函数
swap(a,b);//交换a和b的值
sort(arr.begin(),arr.end());//快速排序,左闭右开,begin()第一个,end()最后一个后边
sort(arr.begin(),arr.end(),greater<int>());
bool cmp(pair<int,int> a,pair<int,int> b){//先排第二位,再排第一位
//第二位从小到大
if(a.second!=b.second)
return a.second<b.second;
//第一位从大到小
return a.first>b.first;
}
vector(pair<int,int>)arr{{1,9},{2,9}{0,1},(0,0)};
sort(arr.begin(),arr.end(),cmp);
for(auto e:arr){
cout<<e.first<<' '<<e.second<<endl;
}
//lower_bound()/upper_bound()
lower_bound()//找大于等于x第一个元素
upper_bound()//找大于x的一个元素
大于x的第一个元素的前一个元素便是小于等于x的一个元素
大于等于x的一个元素的前一个元素便是小于x的第一个元素
#include<bits/stdc++.h>
using namespace std;
int mian(){
vector<int> arr{0,1,1,1,1,8,9,9};
int pos=upper_bound(arr.begin()+2,arr.end(),0)-arr.begin();
cout<<pos<<endl;
return 0;
}
//翻转字符串reverse(起点,终点)
#include<bits/stdc++.h>
using namespace std;
int mian(){
vector<int> arr{0,1,1,1,1,8,9,9};
reverse(arr.begin(),arr.end());
for()
return 0;
}
//max(a,b);最大值
//max({a,b,c,d})//求里面的最大值
//min()同上
//unique()//消除数组的重复"相邻"元素
//消重后会在序列尾部产生无效数据,删除这些无效数据,结合erase
#include<bits/stdc++.h>
using namespace std;
int mian(){
vector<int> arr{0,1,5,2,6,3,9,2};
sort(arr.begin(),arr.end()); /
unique(arr.begin(),arr.end());
arr.earse(unique(arr.begin(),arr.end()),arr.end());
arr.erase();
return 0;
}
//数学函数
abs(-1.0);//取绝对值
exp(2); //e的x次方
log(3);//返回以e为底的ln函数
pow(2,3);//求2的3次方
sqrt(4);//开平方
ceil(2.1);//向上取整
floor(3.2);//向下取整
round(3.2)//四舍五入到整数
向下取整a/b别用floor(1.0*a/b),直接用a/b
向上取整a/b别用ceil(1.0*a/b),直接用(a+b-1)/b
开根号向下取整,别用(int)sqrt(a),用二分查找更快
求a的b次方,别用pow(a,b)用快速幂
别用log2(a),用__lg()
log2(N)=log10(N)/log10(2);//换底公式
gcd()/lcm()//最大公约数/最小公倍数
int gcd(int a,int b){
if(a<b)
swap(a,b);
return gcd(b,a%b);
}
int lcm(int a,int b){
return a/gcd(a,b)*b;
}