(自存)c++ 方法汇总

字符串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 键的键值对的个数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值