DAY4 STL应用学习报告

DAY4 STL应用学习报告

/(课堂笔记)
stack和queue(主要在DAY5)
vector:可变长度数组
map:一二维可以是任意变量且下标可以极大的数组
set:自动去重和排序
multiset:不去重只排序
empty判断是否为空,[begin,end),find(x)!=end()判重
结构体的STL应用与重载运算符 /

尽管STL这一天信息量极大,但是在学习报告里面不会大量的叙述基础概念,学习报告本来就是分享心得体会的,只有比较有意思的问题才会拿来系统的精讲(hanoi上头系列),所以想要初学STL基础知识的读者请移步其他博客。

(注:下文所有的数组名均为数据结构大写,如set用S,map用M)

STL易错知识点 / 细节:

1.对于所有的STL数据结构,其范围都是 [.begin,.end)。常用这一个的是set,S.end()在set中主要功能之二就是结合S.find(x)判重和当做一个空的循环结束条件,而S.end()往往是一个空位置,直接在这个位置insert会RE,所以永远只能对S.end()的上一位进行insert操作,S.begin()的前一位同理(使用upper_bound在set里找第一个(不)小于x的数尤其要注意这一点,即使是写得麻烦一点也要把特判写清楚,否则一个失误很容易大面积RE)。
除此之外,S.end()位置可以进行lower_bound这样的查询,但是返回的值并不是整个set的最后一个值,而是S.size().
———————
2.map后面的变量可以是数组,开出来之后数组就直接是二维的,如map<int,char> M[101].这个数组中的’101’相当于占据了第一维,例子中的M[i][j]中,i就是0-100之间的一个数,j是任意int,M[i][j]是任意char。这种写法基本上等效于map<int,map<int,char> >(注意两层’>'之间必须有空格,否则系统会按位运算符处理),只不过这里的M[i][j]的i是任意int。
———————
3.对于set,需要重载运算符。
———————
4.对于set,为了从中取出元素,需要用迭代器来赋值。迭代器是指针,为了输出指针所指地址的内容(也就是我们实际要的值),需要输出*p。set内的元素和迭代器不能像整形变量进行一般的操作,只能进行等与不等、++、- -的操作。
———————
5.为了把字符串作为下标,需要在声明的时候用string,引用string库,但是还是可以在操作中用char数组。

以下面这道题为例来说明一下用法:
在这里插入图片描述
这道题要我们统计某个单词在哪些句子出现过,由于字符串很难存,所以考虑用二维map,以字母和句子为下标。但是由于句子的数目很多,如果每一个要查询的词都从头至尾查一遍会TLE。由于输出句子是排序的,所以可以用一个set来存句子代替二维map。这样的话,查询的循环次数就只取决于这个单词出现的句子的个数,就避免了时间浪费。

#include<cstdio>
#include<iostream>
#include<map>
#include<set>
#include<algorithm>
#include<string>
using namespace std;
map<string,set<int> > M;
set<int>::iterator l;
int main(){
	int n,i,j,k,m;
	string s,s1;
	scanf("%d",&n);
	for(i = 1;i <= n;i++){
		scanf("%d",&m);
		for(j = 1;j <= m;j++){
			cin >> s;
			M[s].insert(i);
		}
	}
	scanf("%d",&k);
	for(i = 1;i <= k;i++){
		cin >> s1;
		for(l = M[s1].begin();l != M[s1].end();l++){
			if(l != M[s1].begin()) printf(" ");
			printf("%d",*l);
		}
		printf("\n");
	}
	return 0;
}

(注意:为了输出set中的每一位,需要用.begin和.end作限定。但是由于set元素及迭代器的操作只能进行等与不等、++、–,所以要写成l != .end)

STL是对数据结构的扩展,所以也属于一种基础。总之要常练常用,要能够清楚各种数据结构的优缺点和作用。在DAY5会继续重点研究栈、队列等的应用。

Thank you for reading!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值