字符串string
substr( ) 截取子字符串
string a=s.substr(0,3);
string c=s.substr(j+1,s.length());
两种用法:从指定位置开始,字串指定的长度;如若给的是指针,则是到该位置,而非长度
count( ) 统计里面出现的字符的个数
string a;
int num1=count(a.begin(),a.end(),'A');
begin指的是起始地址,end指的是结束地址,第三个参数指的是需要查找的字符
== 关系运算符进行字符串比较
if(sub1==sub2) return true;
关系运算符返回布尔值,根据当前字符特征按字典顺序比较字符
to_string( )字符串string转数字int
string str;
int sum=0;
str=to_string(sum);
stoi( ) 数字int转字符串string
string str = "7";
int num = stoi(str);
demo可用,但是有的时候dev里用不了,只限于c++11版本(慎用)
reverse( )反转字符串
string s;
reverse(s.begin(),s.end());
特别适合回文,或者逆序情况下,但是是对自身作用,如若需要保存原字符串,备份
树
最快找满足最大深度的根结点
题目:A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree.Print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers.
来源:PAT (甲) 1021 Deepest Root (25)
题意:对一个树形结构,寻找以哪个结点为根,深度最大,如果有多个,则升序输出
正常思路:每一个结点都去试,记录每个结点的depth,但是在这里N太大了,测试点3出现了【内存超限】
技巧:(大致思路如下图,见b站up主oldyan_cpp)
step1. 随便找一个结点作为根结点(通常找第一个),找到使其最大深度的叶子结点,保存该结点(可能不止一个),至此某一个端的结点全部找到
step2. 以刚找到的结点为根结点(如果是一组随便选一个),再找到使其最大深度的叶子结点,再保存,与刚刚保存的合并,则为答案
代码如下:
深度搜索部分代码:
vector<int> root1,root;
vector<int> v[10001];
bool vis[10001]={false};
void func(int node,int curh){
if(curh>maxh){
maxh=curh;
root.clear();
root.push_back(node);
}
if(curh==maxh){
root.push_back(node);
}
vis[node]=true;
for(int next:v[node]){
if(!vis[next]) {
func(next,curh+1);
}
}
}
主函数中功能代码:
for(int i=1;i<=N;i++) vis[i]=false;
func(1,0); //step1. 以第一个结点为根结点,因为root会更新,后保存至root1中
root1=root;
for(int i=1;i<=N;i++) vis[i]=false;
func(root[0],0); //step2. 以刚找到的root[0]为根结点
for(auto x:root1) root.push_back(x); //合并两次结果为最终答案
sort(root.begin(),root.end());
set<int> s(root.begin(), root.end());
for(int x:s){
cout<<x<<endl;
}
层序遍历
void bfs(node* T){
queue<node*> q;
q.push(T);//根结点入队
cout<<T->value;//单独处理根,因为空格
if(T->left!=NULL) q.push(T->left);
if(T->right!=NULL) q.push(T->right);
q.pop();
while(!q.empty()){
node* t=new node();
t=q.front();
cout<<" "<<t->value;
if(t->left!=NULL) q.push(t->left);
if(t->right!=NULL) q.push(t->right);
q.pop();
}
}
根据中序inorder和后序postorder建树
node* create(int p1,int p2,int i1,int i2){
if(p1>p2) return NULL;//该区间无意义了,说明遍历完了
//后序的最后一个就是根
node* p=new node();
p->value=post[p2];
int t;//分别找左右孩子,在中序里先找到根的index
for(t=0;in[t]!=post[p2];t++);
p->left=create(p1,t-1-i1+p1,i1,t-1);
p->right=create(t-i1+p1,p2-1,t+1,i2);
return p;
}
dfs
寻找连通子图/联通块
int N,k=0;
vector<int> v[10001];
bool vis[10001]={false};
void dfs(int curi){
vis[curi]=true;
for(int next:v[curi]){
if(!vis[next]) dfs(next);
}
}
int main(){
……
//判断是不是 树
for(int i=1;i<=N;i++){
if(!vis[i]){ //如果没被访问过,则说明为新的连通块
dfs(i);
cnt++;
}
}
cout<<"have: "<<cnt<<" components";
……
}
vector
初始化
vector<int> v; //一个空数组
vector<int> v2{1, 2, 3, 4, 5}; //包含1、2、3、4、5五个变量
vector<int> v3(4); //开辟4个空间,值默认为0
vector<int> v4(arr4.begin(), arr4.end()); //将arr4的值从头开始到尾复制
常用方法
size( ) 返回实际元素的个数
capacity( ) 返回总共可以容纳的元素个数
empty( ) 判断vector是否为空,为空返回true否则false
cout<<v.size()<<endl;
cout<<v.capacity()<<endl;
cout<<v.empty()<<endl;
其中,while(!v.empty()) 常被用做判断数组是否非空条件
单个元素访问
vector可以和数组一样用[]访问元素
front( ) 访问第一个元素
back( ) 访问最后一个元素
cout<<v[0]<<endl;
cout<<v.front()<<endl;
cout<<v.back()<<endl;
循环遍历
C++11的特性,范围for,遍历所有元素十分方便。如果确定x的属性,也可以指定,比如int
for(auto x:v){
cout<<x<<endl;
}
和数组类似,从下标0开始遍历,到size的大小。好处可以指定界限。
for(int i=0;i<v.size();i++){
cout<<v[i]<<endl;
}
push_back( ) 增加、 pop_back( ) 删除 最后一个元素
都是处理最后一个元素
v.push_back(i);
v.pop_back();
insert( ) 插入 、erase( ) 删除 指定位置的元素
v.insert(起始位置, value);
v.insert(v.begin(), 10); //在v的头部插入10
v.erase(起始位置, 结束位置); //左闭右开
v.erase(v.begin(), v.begin() + 2);//删除arr.begin()到arr.begin()+2之间的两个元素
swap( ) 交换两个vector
vector<int> v= {5, 4, 3, 2, 1};
vector<int> v1= { 1, 2, 3, 4, 5 };
v.swap(v1);
clear( ) 清空
清空整个vector,size变为0,但空间仍然存在
v.clear();
去重(利用set的特性)
set<int> s(v.begin(), v.end());
map
unordered_map
特点:无序,查找问题高效一些
#include<unordered_map>
unordered_map<string,int> m1;//将字符转为int,方便处理
unordered_map<int,string> m2;//将int恢复string,方便输出
常见方法
begin(),end(),empty(),size(),clear()
count(key) 在容器中查找以 key 键的键值对的个数。