C++语法基础篇-STL容器和常用函数

STL是提高C++编写效率的一个利器。

STL容器

1.变长数组 vector

/*
	变长数组 Vector  使用倍增的思想 
*/
#include<iostream>
#include<vector>
using namespace std;
int main(){
//定义:	
	vector<int> a; //定义a为存储类型为int 的变长数组
	vector<int> b[100]; //定义b为 第一维长100 第二维为变长的数组 
	
	//自定义结构体 
	struct Rec{
		int x,y;
	}; 
	
	//vector<Rec> c; //自定义的结构体类型也可以保存在vector中 
	
//函数:
	a.size();	//返回vector的实际长度(包含的元素个数) 
	a.empty();	//返回一个bool类型,表明vector是否为空。二者的时间复杂度都是O(1)。
				//所有的STL容器都支持这两个方法,含义也相同,之后我们就不再重复给出。
	a.clear();  //将vector清空 
	
	a.end();//返回的是最后一个元素的下一个地址 
	a.begin(); //a.begin()返回的是a的第一个元素的地址! 
	
	a.front();  //返回vector的第一个元素  等价于a[0] 
	a.back(); 	//返回vector的最后一个元素  等价于a[a.size()-1] 
	
	a.push_back(x); //在a的最后添加一个元素x 
	a.pop_back(); //在移除a的最后一个元素 
	
//迭代器:
	vector<int>::iterator it = a.begin(); //定义一下a的迭代器(类似于指针)
	
	it+2=a[2];  *a.begin()=[0]; //a.begin()返回的是a的第一个元素的地址! 
		
	a.end();//返回的是最后一个元素的下一个地址 
	
//遍历:
	vector<int> d({1,2,3}) ;//初始化一个vector 
	
	//方式一:数组下标
	for(int i=0;i<d.size();i++) cout<<d[i]<<" "; 
	cout<<endl;
	
	//方式二:迭代器遍历  其中vector<int>::iterator 可以用auto替换
	for(vector<int>::iterator i=d.begin();i!=d.end();i++){
	    cout<<*i<<' ';
	}cout<<endl;
	
	//方式三:增强for
	for(auto x:d)cout<<x<<' ';
	cout<<endl;
	
	return 0;
} 

2.队列 queue

/*
	队列 queue 先入先出
*/ 
#include<iostream>
#include<queue>//头文件中包含queue(循环队列)和priority_queue(优先队列)两个容器
using namespace std;
int main(){
//循环队列queue的定义 
	queue<int> q;
	queue<double> a;
	struct Rec{
		int x,y;
	};
	queue<Rec> b;	
//循环队列函数 
	q.push()//对尾插入一个元素
	q.pop(x)//对头移出一个元素
	q.front()//返回队头元素
	q.back()//返回队尾元素
	q=queue<int>(); //重新初始化队列,因为其中不包含清空的函数 
	 
	
//优先队列 priority_queue的定义
	priority_queue<int> a;//默认是大根堆
	priority_queue<int,vector<int>,geater<int>>  b;//小根堆
	priority_queue<pair<int,int>> c;// pair类型
	Rea struct{
		int a,b;
		//重写大于号,因为是属于自定义数据类型,优先队列中比较大小需要我们来自定义一下
		bool operator < (const Rea& t){
			return a < t.a 
		}	
	}; 
	priority_queue<Rea>; 

//优先队列常用函数 
	a.push(x) //插入一个数值
	a.pop() //删除最大值
	a.top() //取出最大值 
	
//特殊指出:队列、优先队列、栈,没有clear函数,清空只需要重新初始化即可!	
	return 0;
}

3.栈 stack

/*
	栈 先入后出 	
*/
#include<iostream>
#include<stack>
using namespace std;
int main(){
//定义	
	stack<int>  stk;
//函数
	stk.push(x) //向栈中插入一个元素x
	stk.pop //	删除栈顶元素 
	stk.top // 返回栈顶元素 
	
	return 0;
}

4.双端队列 deque

/*
	双端队列 deque  队列的两端都可以入和出 
*/
#include<iostream>
#include<deque>
using namespace std; 
int main(){
//deque的定义
	deque<int> a;
//常用函数地址	
	a.begin(); a.end();	 //返回deque的头/尾迭代器 
	a.fornt(); a.back(); //返回deque的头元素或最后一个元素
	
	a[0];//随机取出一个元素
	
	a.clear()//清空所有元素 
	
	push_back(1); push_front(1) //从队尾、对头入队
	pop_back(); pop_back()//从队尾、对头出队
	 
	
	return 0;
} 

5.有序集合 set

/*
	有序集合 set 
*/
#include<iostream>
#include<set> //set头文件中包含 set和multiset两个容器,分别是"有序集合"和"有序多重集合"
			  //前者的元素不能重复,而后者可以包含若干个相等的元素。
			  //set和multiset的内部实现是一棵红黑树,它们支持的函数基本相同。
using namespace std;
int main(){
//定义
	set<int> a;	 //元素不可重复,重复的相关操作默认无效
	multiset<int> b; //元素可以重复
	
	//当set中是自定义结构体类型的数据时,set需要重载 < ,因为我们的set是会将其中元素从小到大排序的
	 
//函数	
	a.size();//实际元素的个数 
	a.clear();//清空 
	a.empty();//判断是否为空 
	
	a.begin();//第一个元素的迭代器 
	a.end();//返回最后一个元素的下一个位置的迭代器 
	
	a.insert(x);//插入一个元素x 
	a.find(x); //返回值为x的迭代器 ,如果找不到返回a.end(); 常用于:if(a.find(x) == a.end()) 
	
	a.lower_bound(x)//找到大于等于 x 的最小元素的迭代器 
	a.upper_bound(x)//找到大于 x 的最小元素的迭代器
	
	a.erase(it)//删除一个迭代器
	a.count(x)//统计x的个数,由于set时有序不重复的,所以存在x返回1不存在返回0
	 
//迭代器
	
	return 0;
}   

6.无序集合 unordered_set

/*
	无序集合unordered_set   底层实现(Hash)哈希表 
*/
//上述set区别,1.其中的元素无序、2.不含upper_bound()和lower_bound()这两个方法,其余一致
#include<iostream>
#include<unordered_set>
using namespace std;
int main(){
	unordered_set<int> a; //不能存放重复元素
	unordered_multiset<int> b;//可以存放重复元素
	 	 
	return 0;
} 

7.键值对 map

/*
	键值对 map //底层实现同set一样是红黑树(平衡树) 
*/
#include<iostream>
#include<map>
using namespace std;
int main(){
//定义
	map<int,int> a;
	map<string,vector<int>>	b;
//函数
	size();empty();clear();begin();end();//均与set类似。
	
	b.insert("sqx",{1,2,3,5});//插入一个<K,V>键值对		
	
	b["sqx"]={1,2,3,5};
	cout<< b["sqx"][2]<<" "<<endl; //输出3 
	
	a.find("sqx");//查询是否存在key 
	return 0;
}

常用函数

1.reverse函数 *

/*
	reverse函数 
*/ 
#include<iostream>
#include<algorithm>
#include<vector> 
using namespace std;
int main()
{
	vector<int> a({1,2,3,4,5});
	int b[]={1,2,3,4,5};
	
	reverse(a.begin(),a.end());
	reverse(b,b+5);  //reverse函数是前闭后开的! 
	
	for(int x : a){
		cout << x <<" ";
	}
	cout<<endl;
	for(int i=0;i<sizeof b;i++){
		cout<< a[i] << " " ;
	} 
	return 0;
} 

2.unique函数

/*
	unique函数 
*/
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
//去重数组	
	int a[] = {1,2,3,4,4,6,6,7,9};
	int m = unique(a,a+9) - a ;  //unique返回的是去重过后最后一个元素的下一个元素的指针!
								 //减去a是为了求得不重复的元素个数 
	for(int i=0 ; i< m ; i++) cout<<a[i]<<" ";
	cout<<endl;
//去重vector
	vector<int> b({1,2,3,4,4,6,6,7,9});
	b.erase(unique(b.begin(),b.end()),b.end()); //将重复元素去除! 
	for(int x : b) cout<<x<<" ";	
	
	return 0;
} 

3.random_shuffle函数

/*
	random_shuffle函数 
*/ 
#include<iostream>
#include<algorithm>
#include<vector>
#include<ctime>
using namespace std;
int main(){
//random_shuffle:打乱数组或Vector中的顺序!
	vector<int> b({1,2,3,4,4,6,6,7,9});
	
	srand(time(0)); //为随机种子传入时间参数,使得每次产生的随机结果都不一样! 
	
	random_shuffle(b.begin(),b.end());
	for(int x : b) cout<<x<<" ";
	cout<<endl;
	
	return 0;
} 

4.sort函数 *

/*
	sort函数 
*/ 
#include<iostream>
#include<algorithm>
#include<ctime>
#include<cstdio> 
using namespace std;
//定义一个结构体类型数组
struct Rec{
	int x,y;
}a[5]; 

//排序条件函数 
bool cmp(int a,int b){  // a是否应该排在b的前面  
	return a<b; //如果a<b,那么a排在b的前面 
}

bool cmp2(Rec a,Rec b){  
	return a.x<b.x; 	//按照结构体中的x的大小,从小到大排序 
}

int main(){
//将随机序列排序sort 
	vector<int> b({1,2,3,4,4,6,6,7,9});
	
	srand(time(0)); //为随机种子传入时间参数,使得每次产生的随机结果都不一样! 
	
	random_shuffle(b.begin(),b.end());
	
	sort(b.begin(),b.end());  //排序 默认是从小到大排序! 
	
	for(int x : b) cout << x << " ";
	cout << endl ; 
//实现从大到小排序,添加参数 greater<int>() 
	sort(b.begin(),b.end(),greater<int>());
		
	for(int x : b) cout << x << " ";
	cout << endl ; 
//自定义排序方式,添加自定义参数cmp
	sort(b.begin(),b.end(),cmp);
		
	for(int x : b) cout << x << " ";
	cout << endl ; 
//为自定义结构体类型数据排序
	for(int i=0;i<5;i++){
		a[i].x=-i;		//初始化数组 
		a[i].y=i;
	} 
	//遍历数组 
	for(int i = 0 ; i < 5 ; i++ ) printf("(%d,%d)",a[i].x,a[i].y);
	cout << endl ;
	
	sort(a,a+5,cmp2);
	for(int i = 0 ; i < 5 ; i++ ) printf("(%d,%d)",a[i].x,a[i].y); 
	return 0;
} 

5.二分函数

/*
	lower_bound  /  upper_bound 二分函数 
*/
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
	int a[] = {1,2,3,4,5,6};
	int *p = lower_bound(a,a+6,x);  //返回的是  >= x的第一个元素的指针 ,
									//如果x大于6那么返回的是a.end(),是个随机数 
	
	cout<< *p <<endl;
	
	
	return 0;
} 
 

6.find函数 *

/*
   find函数 :find()查找第一次出现的目标字符串(全匹配)
			 rfind() 反向查找字符串,即找到最后一个与子串匹配的位置(全匹配)(从前往后搜索)
			   
*/
#include<iostream>
#include<cstdio>
using namespace std;
int main() {
	string s1 = "abcdef";
	string s2 = "de";
	
	int ans = s1.find(s2);//在S1中查找子串S2
	//int ans = s1.find(s2, 2);//从S1的第二个字符开始查找子串S2
	
	cout << ans << endl;
	return 0;
}
//输出结果:3
//find函数查到返回的是 第一个字符的索引!没查到返回-1 
 

7.round函数

这里使用一个四舍五入函数round
对于小数而言,round()函数仅仅保留到整数位,即仅仅对小数点后一位四舍五入,
如果想要保留小数位数,则可以先乘后除
    
思考:4.850000保留一位小数就变成了4.8用的x=(a2+b3+c*4+d)/10,是精度问题吗?
用round函数可得4.9
posted @ 2022-01-23 20:36  爪洼ing  阅读(70)  评论(0编辑  收藏  举报