Week13:STL学习笔记之vector,set/multiset,map

本文介绍了C++中的STL容器,包括vector的基本操作如随机访问、插入、删除,以及set和multiset的特性,它们基于红-黑树实现。同时,还详细讲解了map的映射功能和操作方法,如插入、查找和修改元素。
摘要由CSDN通过智能技术生成

vector

头文件是#include,可以理解成不定长数组。

vector支持随机访问,如同数组操作,可以直接设a[i]访问下标i的位置。它不支持任意位置O(1)插入,这点也如同数组,不如链表插入方便,所以我们一般在vector末尾插入。

声明

vectora;

vectorb[100];

vectorc;(stru为结构体名)

size/empty

size()返回vetor的实际长度,0代表空;而empty()返回一布尔值,判断vector是否为空。

特别强调:所有的STL容器都支持这两个方法,作用也一样。

对于元素的引用一定要记住是左闭右开区间,即for(int i=0;i<a.size();i++)来引用。

clear

clear()清空vector。

迭代器

可以被理解成STL容器的”指针“,可以用”*“操作。使用方法如下:

vector<int>a;
vector<int>::iterator it;
for(it=a.begin();it!=a.end();it++)
	cout<<*it<<endl;

以上代码作用等同于:

for(int i=0;i<a.size();i++)
	cout<<a[i]<<endl;

front/back

front()返回vector的第一个元素,等价于*a.begin()、a[0]。

back()返回vector的最后一个元素,等价于*–a.end()、a[a.size()-1](注意减1)。

push_back/pop_back

a.push_bask(x)把元素x插入到vector a的末尾。

a.pop_back()删除vector a的最后一个元素,无值返回。

set/multiset

头文件是#include,set是“有序集合”,而multiset是“有序多重集合”。前者的元素不能重复,而后者可以包含若干个相同的元素。两者内部实现都是“红—黑树”,查询复杂度为O(lgn)。

强调set不支持“随机访问”,必须使用迭代器进行访问使用。

声明

seta;声明了一个去除了重复元素的从小到大的有序集合a。

multisetb;声明了一个允许重复且从小到大的集合b。

size/empty/clear

如同vetor操作,功能一致。

迭代器++/–

set::iterator it;

it++访问“下一个”元素

it–访问“上一个”元素

注意:只支持++和–操作,不支持+和-操作,且操作的时间复杂度为O(lgn)。

begin/end

a.begin()返回有序集合中最小元素给迭代器,不是具体值。

a.end()返回有序集合中最大的元素的“下一个”位置给迭代器,如果要返回最大值的位置,则要–a.end()(因为“左闭右开”原则)。

insert

a.insert(x)把一个元素x插入到集合a中,时间复杂度为O(lgn)。注意set和multiset关于重复元素的区别。

例如下面代码的功能是把n个元素插入到有序多重集合a中,并从小到大输出该集合的所有元素。时间复杂度为O(n*lgn),相当于进行了一次排序。

multiset<int>a;
for(int i=1;i<=n;i++)
{
	int x;
	cin>>x;
	a.insert(x);
}
for(multiset<int>::iterator it=a.begin();it!=a.end();it++)
	cout<<*it<<" "<<endl;

注意访问是使用迭代器操作,不能直接引用。

find

s.find(x)在集合s中查找等于x的元素,并返回指向该元素的迭代器。若不存在,则返回s.end()。时间复杂度为O(lgn)。

lower_bound/upper_bound

这两个函数的用法与find类似,但查找的条件不同,时间复杂度为O(lgn)。

s.lower_bound(x)查找>=x的元素中“最小”的一个,并返回指向该元素的迭代器。如果不存在返回s.end()。

s.upper_bound(x)查找>x的元素中“最小”的一个,并返回指向该元素的迭代器。如果不存在返回s.end()。

举个例子,输出multiset集合中元素为x的个数:

int sum=0;
int x;
cin>>x;
for(multiset<int>::itetator it=s.lower_bound(x);it!=s.upper_bound(x);it++)
{
	sum++;
}

可以看出,lower_bound指向与x相等的“第一个”元素;而upper_bound指向与x元素相等的“最后一个”元素的下一个元素的迭代器。

erase

设it是一个set迭代器,s.erase(it)是删除集合s中迭代器it指向的元素,时间复杂度为O(lgn)。

设it是一个multiset迭代器,要删除该集合中所有等于x的元素,则写成:

while(it=s.find(x)!=s.end())
	s.erase(it);

count

s.count()返回集合s中元素的个数。

map

头文件是#include,实战中当作hash使用,建立从复杂信息的key(如字符串)到简单信息value(如一定范围内的整数)的映射。其内部是一棵以key为关键字的红—黑树。map容器对key-value的类型可以是任意类型,但其中的key必须定义“<(小于号)”运算符。

声明

格式为:map<key_type,value_type>name。

map<int,int>a;

map<string,int>b;

map<pair<int,int>,vector >t;

迭代器

map的迭代器与set一样,返回的是一个二元组pair<key_type,value_type>。

insert/erase/find

与set类似,分别为插入、删除、查找操作。insert的参数是pair<key_type,value_type>,erase的参数可以是pair或者是迭代器。

h.find(x)在map中查找key=x的二元组,找到则返回二元组的迭代器,没有找到则返回h.end()。

[]操作符

h[key]=value改变key对应的value,x=h[key]把key所映射的value返回给变量x。这是map应用最吸引人的地方,操作方便,时间复杂度为O(lgn)。

强调:若查找的key不存在,则执行h[key]后,h会自动新建一个二元组(key,zero),并返回zero的引用。这里的zero表示一个广义的“零”,如整数0、空字符串等。所以,如果反复查找的key都不存在,这样map会开设许多”无用“的zero,白白浪费空间。所以我们在用h[key]操作之前,必须用find方法检查key的存在性。

【实例】用map统计字符串出现的次数。

给定n个字符串,m个问题,每个问题询问一个字符串出现的次数。n,m<=20000,每个字符串的长度不超过20。

#include<bits/stdc++.h>
using namespace std;
int main()
{
	map<string,int>h;
	string str;
	int n,m;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>str;
		h[str]++;
	}
	cin>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>str;
		if(h.find(str)==h.end())
			cout<<0;
		else
			cout<<h[str];
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值