蓝桥杯算法练习笔记(5)__常用的STL

6.常用STL

1.动态数组Vector
1.基本操作
//基本操作 
#include<iostream>
#include<vector>
using namespace std;

int main(){
	vector<int>vec;
	vec.push_back(1);
	vec.push_back(2);
	vec.push_back(3);//[1,2,3]
	vec[1]=4;//[4,2,3]
	vec.pop_back();//[4,2]
	for(int i=0;i<vec.size();i++){
		cout<<v[i]<<endl;
	}
	vec.clear();//清空数据,不清空内存
	 
	return 0;
}
2.存放自定义数据类型
//存放自定义数据类型(例结构体) 
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;

struct Student{
	string name;
	int age;
}; 

int main(){
	vector<Student> class1;
	Student stu1,stu2;
	stu1.name="Adime";
	stu2.name="Sada";
	stu1.age=19;
	stu2.age=28;
	class1.push_back(stu1);
	class1.push_back(stu2);
	return 0;
}
3.二维动态数组
/*动态数组的初始化:*/
	vector<int>a(n);//n个元素,每个元素为0
	vector<int>a(n,m);//n个元素,每个元素为m

/*二维动态数组:*/
#include<iostream>
#include<vector>
#include<cstring>
using namespace std;

int main() {
	//创建
	vector< vector<int> > vec2;
	int n,m;
	cin>>n>>m;

	//(可理解为)开辟空间/初始化
	// resize() 设置 vector 的大小
	vec2.resize(n);//行数为n
	for(int i=0; i<n; i++) { //每行列数为m
		vec2[i].resize(m);
	}

	//赋值
	for(int i=0; i<n; i++) {
		for(int j=0; j<m; j++) {
			cin>>vec2[i][j];
		}
	}

	//遍历
	for(int i=0; i<vec2.size(); i++) {
		for(int j=0; j<vec2[i].size(); j++) {
			cout<<vec2[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}


/*快速构建二维动态数组*/
	vector< vector<int> > vec2(n,vector<int>(m,0));
2.集合Set
1.基本操作
/*特点*/
	集合内的元素不重复,自动升序排序
#include<iostream>
#include<set>
using namespace std; 
int main(){
	set<int> se;
	se.insert(1);//插入
	se.insert(1);//重复元素无法插入,不报错 
	se.insert(2);
	se.insert(3);
	se.insert(4);
	se.insert(0);
	se.erase(1);//删除一个元素
	se.erase(5);//不存在的元素无法删除,但也不报错 
	if(se.count(2)){
		cout<<"2存在."<<endl; 
	}
	//用迭代器进行遍历
	set<int>::iterator it;
	for(it=se.begin();it!=se.end();it++){
		cout<<*it<<" ";
	} 
	
	se.clear();//清空数据,清空内存 
	
	return 0;
}
 
2.存放自定义数据类型
#include<iostream>
#include<set>
using namespace std; 

//set中的结构体
struct Point{
	int x,y;
	//重载小于号 
	//rhs 是 right hand side 的简称 
	bool operator<(const Point &rhs) const{
		if(x==rhs.x){
			return y<rhs.y;
		} else{
			return x<rhs.x;
		}
	
	}
}; 

int main(){
	int n;
	cin>>n;
	set<Point> v;
	for(int i=0;i<n;i++){
		Point temp;
		cin>>temp.x>>temp.y;
		v.insert(temp);
	}
	for(set<Point>::iterator it=v.begin();it!=v.end();it++){
		cout<< it->x <<" "<< it->y <<endl;
	}
	return 0;
}
 
/*
输入:
6
5 6
1 2
2 1
3 4
1 2
1 1

输出: 
1 1
1 2
2 1
3 4
5 6 
*/
3.栈
#include<iostream>
#include<stack>
using namespace std;
int main(){
	stack<int> s;
	s.push(1);//进栈 
	s.push(2); 
	s.push(3); 
	s.pop();//出栈
	cout<<s.top()<<endl;//获取栈顶//2
	if(!s.empty())//判空 
		cout<<s.size()<<endl;//获取栈元素个数//2 
}
4.队列
#include<iostream>
#include<queue>
using namespace std;
int main(){
	queue<int> que;
	que.push(1);//入队 
	que.push(2);
	que.push(3);
	que.pop();//出队
	cout<<que.front()<<endl;//获取队首 //2
	cout<<que.back()<<endl;//获取队尾 //3
	if(!que.empty())
		cout<<que.size()<<endl;//获取元素个数 //2 
	return 0;
} 
5.优先队列 priority_queue
可以用 优先队列 实现堆

priority_queue < 数据类型,底层用什么结构存储数据,比较大小的函数> 

STL里面默认用的是 vector. 比较方式默认用 operator< 

如果把后面俩个参数缺省的话,优先队列就是大顶堆,队头元素最大。----降序

注:优先队列没有 q.front() 和 q.back()

#include<iostream>
#include<queue> 
using namespace std;

int main(){
	int n,x;
	cin>>n; 
	priority_queue<int,vector<int>,greater<int> > q; //升序 
	// prioity_queue<int> q;  // 降序 
	for(int i=0;i<n;i++){
		cin>>x;
		q.push(x);
	} 
	
	//cout<<q.front()<<" "<<q.back()<<endl; 
	
	while(!q.empty()){
		cout<<q.top()<<" ";
		q.pop();
	}
	cout<<endl;
	
	return 0;
} 
/*
--cin:
5
1 5 9 3 7
--cout: 
1 3 5 7 9
*/
6.映射Map
1.基本操作
/*两个"集合"之间的对应关系,关键字集合,值集合*/
/*关键字集合里面没有相同的值,插入不会更改*/
/*按照key值自动从小到大排序*/

#include<iostream>
#include<map>
#include<cstring>
#include<utility>
using namespace std;

int main() {
	map<string,int> dict;
	dict.insert(make_pair("Tom",1));//插入,需要头文<utility> 
	dict.insert(make_pair("Aam",2));
	dict.insert(make_pair("IlS",3));
	dict["Bia"]=5;//赋值/插入 
	dict["Uia"]=3; 

	if(dict.count("Tom"))//判断是否存在
		cout<<"Tom is "<<dict["Tom"]<<endl; //访问
	else
		cout<<"not find Tom"<<endl;
	
	//遍历 
	for(map<string,int>::iterator it=dict.begin(); it!=dict.end(); it++) {
		cout<<it->first <<" "<< it->second <<endl;
	}


	return 0;
}
2.二维map之map套set
//二维map之map套set 
#include<iostream>
#include<map>
#include<cstring>
#include<set>
using namespace std;
/*对全校姓名进行统计,避免不同班级的相同姓名的人无法录入,
对每个班级建立一个set(假设班内无重名),组成一个映射*/
int main() {
	
	map<int,set<string> > s; 
	s[2].insert("小A");//2班有一个名字叫小A的同学
	
	return 0;
}
~~~

~~~C++
//二维map之map套map 
#include<iostream>
#include<map>
#include<string>
using namespace std;
int main() {
	
	map<int,map<string,int> >info;
	
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		int class_id;
		string name;
		cin>>class_id>>name;
		info[class_id][name]++;
 
	} 
	
	for(map<int,map<string,int > >::iterator it1=info.begin();it1!=info.end();it1++){
		for(map<string,int>::iterator it2=it1->second.begin();it2!=it1->second.end();it2++)
			cout<<"There are "<<it2->second<<" people named "<<it2->first<<" in class "<<it1->first<<endl;
	}
	
	return 0;
}
/*
输入案例:
	4
	1 zgh
	2 yuhaoran
	2 yuhaoran
	1 rar 

输出案例:
	There are 1 people named rar in class 1
	There are 1 people named zgh in class 1
	There are  people named yuhaoran in class 2
*/
7.STL练习
#include<iostream>
#include<vector> 
using namespace std;
/*锯齿数组(每行的元素个数都不相同)
一开始数组为空,输入若干组(x,y),表示在x位置插入数据y 
输出最后的锯齿数组 
*/
vector<int> mat[10005];

int main(){
	int n,m,x,y;//n锯齿数组的行数,m插入的总数 
	cin>>n>>m;
	for(int i=0;i<m;i++){
		cin>>x>>y;
		mat[x].push_back(y); 
	}
	
	for(int i=1;i<=n;i++){
		for(int j=0;j<mat[i].size();j++){
			cout<<mat[i][j]<<" ";
		}
		cout<<endl;
	}
	
	return 0;
}

/*
输入: 
3 12
1 3
2 2
2 3
2 4
3 1
3 6
1 5
1 2
1 6
3 2
3 7
1 1
输出: 
3 5 2 6 1
2 3 4
1 6 2 7
*/

1.蒜头君堆积木问题 题目链接
在这里插入图片描述

#include<iostream>
#include<vector>
#include<string>
using namespace std;
vector<int> v[10005];
int main() {
	int n,m,a,b;
	cin>>n>>m;
	//初始化
	for(int i=1; i<=n; i++) {
		v[i].push_back(i);
	}
	//
	for(int i=0; i<m; i++) {
		cin>>a>>b;
		if(a==b) {
			continue;
		}
		for(int j=0; j<v[b].size(); j++) {
			v[a].push_back(v[b][j]);
		}
		//清除
		vector<int>().swap(v[b]);
	}

	for(int i=1;i<=n;i++){
		for(int j=0;j<v[i].size();j++){
			cout<<v[i][j]<<" "; 
		}
		cout<<endl;
	}
	
	
	return 0;
}

/*
输入: 
4 4
3 1
4 3
2 4
2 2
输出: 
2 4 3 1
*/

2.蒜头君的水果店 题目链接
在这里插入图片描述

#include<iostream>
#include<map>
#include<string>
using namespace std;

int main() {

	map<string,map<string,int> > mp;
	string s1,s2;
	int d;
	
	int n;
	cin>>n;
	for(int i=0;i<n;i++){
		cin>>s1>>s2>>d;
		mp[s2][s1]+=d;
	}
	
	for(map<string,map<string,int> >::iterator it1=mp.begin();it1!=mp.end();it1++){
		cout<<(it1->first)<<endl;
		for(map<string,int>::iterator it2=(it1->second).begin();it2!=(it1->second).end();it2++){
			cout<<"   |----"<<(it2->first)<<"("<<(it2->second)<<")"<<endl; 
		}
	}
	return 0;
}
/*
输入: 
5
apple shandong 3
pineapple guangdong 1
sugarcane guangdong 1
pineapple guangdong 3
pineapple guangdong 1

输出: 
guangdong
   |----pineapple(5)
   |----sugarcane(1)
shandong
   |----apple(3)
*/

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值