文章目录
1. C++知识的补充
C++ 相对于C语言的基础上就添加了面向对象和模块的思想,但是C++在C语言的基础上加了一些库函数,但是这些库函数非常好用,在一些算法比赛中经常用到
2. cin和cout的使用
cin和cout是c++中的标准输入输出流。
2.1cin
cin的一般用法:cin>>变量a>>变量b>>变量c;
cin会自动辨别变量的类型,如a可以是char,b可以是int,c可以是float。接收字符串时,遇到空格,tab键和换行符都会结束接收。
cin.getline()可以接收空格,cin.getline(char*,int,char),内有三个参数,第一个表示要接收的字符串,第二个表示接收字符个数,第三个表示结束字符。当第三个省略时默认结束字符为’\0’。
2.2cout
cout的一般用法:
cout<<表达式1<<表达式2<<表达式3;如要换行可使用 cout<<endl;语句。
和cin一样,cout会自动检测表达式类型输出
cin和cout与C语言中的scanf、printf相比消耗时间比较多,在一些算法题目中容易超时
3. STL函数库
STL是c++中的一个标准模板库,作为C++标准不可缺少的一部分,里面的一些函数可方便我们的使用
3.1vector
vector被翻译为向量也称作变长数组吗,长度或根据需要自动的改变,自动扩容,可以避免普通数组超内存的情况,但是vector会方便很多
vector的定义
使用vector要记得加上头文件 #include<vector>
vector<typename> name;
vector<int> vi;
vector<double> vi;
vector<char> vi;
vector<node> vi;//node可以是结构体
3.1.1vector常用的方法
clear()清空
resize()改变大小
size()获取元素的多少
push_back()在尾部添加元素
pop_back()在尾部删除元素
empty()测试是否为空
vector之间可以直接赋值或者作为函数的返回值
back() 返回vector里的最后一个元素
front() 返回vector里的第一个元素
3.1.2vector的访问方式
1.通过下标方式遍历
for(int i=0;i<5;i++)
{
vi.push_back(i);
}
for(int i=0;i<vi.size();i++)//通过下标方式遍历
{
cout<<vi[i]<<" ";//0 1 2 3 4
}
- 通过迭代器遍历
vector<typename>::iterator it可以把它看做类似于指针的东西
vi[i]和(vi.begin()+i)是等价的
vi.begin()和vi.end()是左开右闭的end()表示的是尾元素的下一个
迭代器支持++,--的操作
迭代器不支持it<end()写法,因此循环条件只能用it !=vi.end()
for(vector<int>::iterator it=vi.begin();it!=vi.end();it++)
{
cout<<*it<<" ";//0 1 2 3 4
}
3.1.3insert()
向vector的任意迭代器it处插入一个元素x
注意第一个参数必须是迭代器
for(int i=0;i<5;i++)
{
vi.push_back(i);
}
vi.insert(vi.begin()+2,8);//在下标为2的地方插入8
for(int i=0;i<vi.size();i++)
{
cout<<vi[i]<<" ";//0 1 8 2 3 4
}
3.2 string类
string是C++标准库的一个重要的部分,主要用于字符串处理。可以使用输入输出流方式直接进行string操作,也可以通过文件等手段进行string操作。同时,C++的算法库对string类也有着很好的支持
3.2.1 string类的定义
定义string类的方式跟基本数据类型相同,只需要在string后跟上变量名即可
string str;
如果要初始化,可以直接给string类进行赋值
string str="hello";
3.2.2 string的输入和输出
如果要读入和输出字符串只能用cin和cout
cin>>str;
cout<<str;
如果读入带有空格等等的字符串
getline(cin,str);
如果要用printf输出string类型
printf("%s",str.c_str());
3.2.3 string类的访问
直接通过下标访问
string str="abcdef";
for(int i=0;i<str.length();i++){
cout<<str[i];
}
通过迭代器访问
for(string::iterator it=str.begin();it!=str.end();it++){
cout<<*it;
}
3.2.4 String的常用操作
- string类可以直接进行加法,可以将两个string类拼接起来
- string类可以直接比较大小 是按字典序排的(从首字母开始每一位比较大小,比较的是ASCII码,直到有一位不一样,比较出结果)
- length() size() 返回string的长度
- insert(pos,string) 在pos号位置插入字符串string
- erase()
删除单个元素 erase(it) 用于删除单个元素 it为要删除的元素的迭代器
str.erase(first,last) first为要删除区间的其实迭代器,last为需要删除的末尾迭代器的下一个地址
str.erase(pos,length) pos为要删除的起始地址 length为要删除的字符个数
// 删除单个元素 erase(it) 用于删除单个元素 it为要删除的元素的迭代器
string s1="abcdef";
s1.erase(s1.begin()+3);
cout<<s1<<endl;//abcef
//删除一个区间内的所有元素
//str.erase(first,last) first为要删除区间的其实迭代器,last为需要删除的末尾迭代器的下一个地址
string s2="abcdef";
s2.erase(s2.begin(),s2.begin()+4);
cout<<s2<<endl;//ef
//str.erase(pos,length) pos为要删除的起始地址 length为要删除的字符个数
string s3="abcdef";
s3.erase(2,4);
cout<<s3<<endl;//ab
- clear() 清空string中的数据
- find()
str.find(str2) 当str2是str的子串时,返回其在str中第一次出现的位置,如果str2不是str的子串返回-1
str.find(str2,pos)从str的pos号位开始匹配str2
//str.find(str2) 当str2是str的子串时,返回其在str中第一次出现的位置,如果str2不是str的子串返回-1
string ss1="abcdefabc";
string ss2="abc";
int pos=ss1.find(ss2);
cout<<pos<<endl;//0
//str.find(str2,pos)从str的pos号位开始匹配str2
int pos1=ss1.find(ss2,3);
cout<<pos1<<endl;//6
int pos2=ss1.find("xyz");
cout<<pos2<<endl;//-1
- replace()
- str.replace(pos,len,str2)
3.3 set
set集合,是一个内部自动有序且不含重复元素的容器
3.3.1set的定义
set<typename> name;
set<int> vi;
set<double> vi;
set<char> vi;
set<node> vi;//node可以是结构体
set<int> a[100]; //数组里面每个元素都是一个set集合
insert(x) 将x插入set容器中,并自动递增排序和去重
//insert(x) 将x插入set容器中,并自动递增排序和去重
st.insert(4);
st.insert(3);
st.insert(1);
st.insert(2);
//不支持<it.end()的写法
for(set<int>::iterator it=st.begin();it!=st.end();it++){
cout<<*it<<" ";//1 2 3 4
}
3.3.2 set集合的遍历
set只能通过迭代器遍历
除了vector和string之外的stl容器都不支持*(it+i)的访问方式
set内的元素会自动递增排序,且自动去除了重复元素
//不支持<it.end()的写法
for(set<int>::iterator it=st.begin();it!=st.end();it++){
cout<<*it<<" ";//1 2 3 4
}
3.3.3 其他函数的使用
- find(value)
返回set中对应值为value的迭代器,如果查找元素不存在会返回最后一个元素的迭代器 - erase()删除元素
//erase() 有两种用法一种是删除单个元素另一种是删除一个区间的所有元素
//删除单个的方法又有两种
//1.st.erase(it) it为所删元素的迭代器 可以和find连用
//1 2 3 4
st.erase(st.find(3));
for(set<int>::iterator it=st.begin();it!=st.end();it++){
cout<<*it<<" ";//1 2 4
}
cout<<endl;
//2.st.erase(value) value为所删除元素的值
//1 2 4
st.erase(1);
for(set<int>::iterator it=st.begin();it!=st.end();it++){
cout<<*it<<" ";//2 4
}
cout<<endl;
st.insert(4);
st.insert(3);
st.insert(1);
st.insert(2);
//删除整个区间
//1 2 3 4
st.erase(st.find(2),st.end());
for(set<int>::iterator it=st.begin();it!=st.end();it++){
cout<<*it<<" ";//1
}
- size():返回set内的元素个数
- clear():清空set中的所有元素
- empty(): 判断是否为空
3.4 map
3.4.1 map的定义
map需要确定映射前类型(键key)和映射后类型(值 value) <>内填写两个类型,其中第一个键的类型,第二个是值的类型,如果是字符串到整形的映射,必须使用string而不用char数组类型
map<typename1,typename2> mp;
map<int,int> mp;
map<string,int> mp;
map<set<int>,string> mp;
3.4.2 map容器的内元素的访问
通过下标访问
和访问普通数组一样,例如对一个定义为map<char,int> mp的map来说,就可以直接使用mp[‘c’]的方式来访问它对应的整数,map中的键值是唯一的
map<char,int> mp;
mp['c']=1;
mp['c']=2;//1被覆盖
cout<<mp['c']<<endl;//2;
通过迭代器返回
map<typename1,typename2>::iterator it;
for(;it!=mp.end();it++)
{
cout<<it->first()<<" "<<it->second()<<endl;
}
map可以使用it->first来访问键,使用it->second来访问值
3.4.3 map容器的其他函数
- find():find(key) 返回键值为key的映射迭代器,如果不存在执行迭代器的最后一个元素
- erase():删除元素
- 有两种用法 删除单个元素,删除一个区间内的所有元素
mp.erase(it) it为所需要删除元素的迭代器
map<char,int> mp;
mp['a']=1;
mp['b']=2;
mp['c']=3;
map<char,int>::iterator it;
it=mp.find('a');
mp.erase(it);
for(it=mp.begin();it!=mp.end();it++){
cout<<it->first<<" "<<it->second<<endl; //b 2 c 3
}
mp.erase(key) key为欲删除的映射的键
map<char,int> mp;
mp['a']=1;
mp['b']=2;
mp['c']=3;
map<char,int>::iterator it;
mp.erase('b');
for(it=mp.begin();it!=mp.end();it++){
cout<<it->first<<" "<<it->second<<endl;
}
- 删除一个区间内的所有元素
mp.erase(first,last) 其中first为需要删除的区间的起始迭代器,而last则为所需要删除的区间的末尾迭代器的下一个地址,也即为删除左闭右开的区间
map<char,int> mp;
mp['a']=1;
mp['b']=2;
mp['c']=3;
mp['d']=4;
mp['e']=5;
map<char,int>::iterator it;
it=mp.find('b');
mp.erase(it,mp.end());
for(it=mp.begin();it!=mp.end();it++){
cout<<it->first<<" "<<it->second<<endl; //a 1
}
- clear()清空map集合中的所有元素
- size()获得map中映射的对数
3.5 stack
大家刚学完数据结构是不是每次用栈和队列都很麻烦还要建链表…stl真的很方便帮我们都写好了栈的相关操作,我们直接用就可以了
stack是一种先进后出的数据结构
3.5.1 stack的定义
首先需要加头文件#include <stack>
h或者万能头文件
stack的定义
stack<typename> name
3.5.2常用方法
- push:将元素压入栈
- top():取出栈顶元素
- pop:弹出栈顶元素
stack不能通过下标访问,只能通过top()来取栈顶元素访问
- empty:判断栈是否空
- size:获取stack内的元素
3.6 队列
队列是常用的一种数据结构,具有先进先出的优先,stl封装了一些队列的操作,为我们开发提供了方便
3.6.1 queue的定义
需要先加头文件#include <queue>
或者万能头文件
3.6.2 相关的操作
- push(x):将x进行入队
- front():取队首元素
- back():取队尾元素
- pop():首元素出队
- empty():是否为空
- size():检查队列的大小
队列也是没有clear()函数的如果想要清空还是得遍历
3.7 algorithm头文件下的常用函数
max,min,abs
max(x,y)和min(x,y) 求两个值中的最大值,最小值
abs(x)x必须是整形
int a=3,b=4,c=-5;
cout<<max(a,b)<<endl; //4
cout<<min(a,b)<<endl; //3
cout<<abs(c)<<endl //5;
swap
swap(x,y)交换两个值
int a=1,b=2;
swap(a,b)
cout<<a<<endl;//2
cout<<b<<endl;//1
fill()
fill可以把数组或容器中的某一段区间复制为某个值
//清空数组
int a[100];
fill(a,a+100,0);
memset(ans,0,sizeof(ans));//memset是按字节赋值的
reverse()
reverse(it1,it2)可以将数组指针在[it1,it2)之间的元素或容器的迭代器在[it1,it2)范围内的元素进行反转
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a[5]={1,2,3,4,5}
reverse(a,a+5)
for(int i=0;i<5;i++)
{
cout<<a[i[<<" "; // 5 4 3 2 1
}
string s="abcdefg";
reverse(s.begin(),s.begin()+3);
cout<<s;//cbadefg
return 0;
}