C++ STL库用法实例

你还在担心不会用auto写for循环吗?
你还在担心map不会用吗?
你还在为STL的各种库不会用而苦恼吗?
相信我,看了这篇文



你依然不会!
题目传送门—>CF977B Two-gram
题目描述:
给你一个字符串,找出现次数最多的长度为2的子串。
输入样例:
7
ABACABA
输出样例:
AB
这道题可以作为C++ STL库的优质练手题

1.auto的循环遍历

for(auto x : range)
创建拷贝,无法修改range中的元素
for(auto& x : range)
可以修改range中的元素,但一般用这种for(auto&& x : range)
for(const auto & x : range)
只读range中的元素

2.string中截取字符串
ss.substr(i,k):
这个的意思就是从i开始截取以k为单位长度的一个字符串,k指代的是长度。
ss.c_str():
这个就是将string字符串转化成为C的字符串数组,而c_str();则是生成一个const char*类型的指针,指向字符串的首地址

#include<iostream>
#include<string>
#include<cstring>
using namespace std;
int main(){
	char s[10];
	string a="hello world!";
	strcpy(s,a.c_str());
	cout<<s;	
}

不妨可以试试.

#include<iostream>
#include<string>
#include<map>
#include<vector>
using namespace std;
int main(){
	string ss;
	string ans;
	map<string,int>f;
	int u;
	cin>>u;
	cin>>ss;
	//u=-1;
	u=0;
	for(int i=0;i<ss.size()-1;i++){
		f[ss.substr(i,2)]++;
		//注意这里的substr(i,k)是string中的库函数
		//这个的意思就是从i开始截取以k为单位长度的
		//一个字符串 
	}
	//遍历数组
	ans=ss.substr(0,2);
	for(auto &&i:f){
		if(i.second>u){
			u=i.second;
			//cout<<u<<endl; 
			ans=i.first.c_str(); 
		}
	} 
	cout<<ans;
	return 0;
}

如果map这么定义:map < string , map < string , int > >
那么应该:
for(auto&&p:m)
for(auto&&p2:p.second)

下面一道题是关于set的用法

题目传送门—>CF620C Pearls in a Row

现在有N个数,你的任务是将这N个数尽可能切割成多段。每一段必须包括两个相同的数。

数据输入量比较大,建议使用scanf和printf。

Input 单组测试数据。数据第一行为N(1 ≤ N ≤ 3·105) 。

数据的第二行包括N个数ai(1 ≤ ai ≤ 109) 。

Output 输出的第一行为尽可能切割的最大段数K。

接下来K行,每行为两个整数lj, rj (1 ≤ lj ≤ rj ≤ n) ,表示切割的区间范围

如果存在多个合法的切割方法,输出任意一个即可。

如果不能切割成合法的情况,输出"-1".

这道题涉及一小部分贪心

首先讲一下set:

#include <set>//头文件
set <int> st//定义set,我喜欢用st命名
set.insert(a)//插入数据
set.count(a)//查找数据是否出现
set.clear()//清空

快读模板

inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}

这道题的思路就是用set找到相同的数字了以后就把这个区间切开,但是本道题代码实现相对来说很巧妙,下面请看。

#include<iostream>
#include<set>
using namespace std;
set<int>p;
int l[1010102],r[1010212];
int a[1021021];
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0' && ch<='9'){
        x=(x<<1)+(x<<3)+(ch^48);
        ch=getchar();
    }
    return x*f;
}//快读,常数优化大佬中的大佬,不会的赶紧学一下吧!
int main(){
	int n;
	n=read();
	l[1]=1;
	int u=0;
	for(int i=1;i<=n;i++)	a[i]=read();
	for(int i=1;i<=n;i++){
		if(p.count(a[i])==1){
			++u;
			r[u]=i;
			l[u+1]=i+1;
			p.clear();//已经裁剪,全部清空 
			//这道题的大致意思就是我们找到重复的了
			//那么就说我们我们找到了一组可裁剪区间
			//l[1]=1说明我们裁剪的话肯定先要裁剪第一个
			//然后让下一位裁剪的位置指向下一个第一位
			//确定完裁剪区间以后,我们就认为这个区间和
			//我们题干中的数组没关系了,就清空set集合
		}else p.insert(a[i]); 
		/*if(p.count(a[i])==1){
			r[u]=i;
			l[++u]=i+1;
			p.clear();//已经裁剪,全部清空 
		}else p.insert(a[i]); **////这个是错的!注释的部分和答案不一样的地方在于
		//
	}
	r[u]=n;//这个是精髓之处
	//比方说1 2 2 2 2 1 3    本来r[1]=6,但是为了让最后的数字包括上
	//就自动赋值让r[1]=7
	if(u==0){
		printf("-1\n");
		return 0;
	}
	else {
		/*if(r[u-1]==n){
			cout<<u-1<<endl;
			for(int i=1;i<u;i++){
				cout<<l[i]<<' '<<r[i]<<' ';
			}
		}else */{
			cout<<u<<endl;
			for(int i=1;i<=u;i++){
					cout<<l[i]<<' '<<r[i]<<endl;
			}
		}
	}
	return 0;
	
}

priority_queue C++ STL库中的优先队列

头文件:#include 和普通的queue不一样的地方在于:可以自定义数据的优先级(权重),让权重高的排在队列的前方,优先出队。本质上是堆的一个实现。

定义:priority_queue<Type, Container, Functional>
Type 就是数据类型,Container 就是容器类型(Container必须是用数组实现的容器,比如vector,deque等等,但不能用 list。STL里面默认用的是vector),Functional 就是比较的方式。

当需要用自定义的数据类型时才需要传入这三个参数,使用基本数据类型时,只需要传入数据类型,默认是大顶堆。
//升序队列,小顶堆(从小到大输出)
priority_queue <int,vector,greater > q;
//降序队列,大顶堆 (从大到小输出)
priority_queue <int,vector,less >q;

//greater和less是std实现的两个仿函数(就是使一个类的使用看上去像一个函数。其实现就是类中实现一个operator(),这个类就有了类似函数的行为,就是一个仿函数类了)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值