C++关联容器知识总结


最近学习了C++中关联容器的一些知识,在此总结加深记忆并方便复习,同时也希望能帮助到想了解C++关联容器相关知识的朋友。

类型

C++11中共有八种关联容器,分别为map,set,multiset,multimap,unordered_map,unordered_set,unordered_multimap,unordered_multiset。其中带multi的表示关键字可重复,带unordered表示为无序容器,无序容器使用哈希函数组织。map与set之间的不同主要是map为键值对,而set只有键。

声明及初始化

与vector,list等一样,map与set也是模板,下面定义了一个关键字(key)为string类型,值(value)为int类型的map以及类型为string的set:

std::map <std::string,int> m_map;
std::set <std::string> m_set;

可以用下面的方式来进行初始化:

std::map <std::string,int> m_map={{“Hi",1},{"Ha",3},{"He",10}};
std::set<std::string> m_set={"La","Ha","Hi"};

关键字类型与自定义比较函数

对于有序容器(map,set,multimap,multiset),关键字类型必须定义元素比较的方法,默认情况下,标准库使用关键字类型的<运算符来比较元素。无序容器的要求我暂时还没弄明白。。由于这个要求,当我们的键值类型为我们自己定义的类或某些没有定义<的类型时,我们必须为该类型重载<运算符或定义比较函数,且要遵循严格弱序
例子如下:

class Sales_data
{
	private:
		int isbn;
	public:
		int GetIsbn()
		{
			return isbn;
		}
}
bool Compare(const Sales_data &s1,const Sales_data &s2)
{
	return s1.GetIsbn()<s2.GetIsbn();
}

std::multiset<Sales_data,decltype(Compare)*> bookStore(Compare);

使用decltype来指出自定义操作类型,加上星号来表示这是一个函数指针,然后使用Compare来初始化bookStore对象,当向bookStore中添加元素时将调用Compare来为对象排序。

操作

类型

key_type	//map中为第一个参数的类型,set即为其唯一的参数类型
mapped_type	//map独有的类型,就是其值类型
value_type	//map为pair<const key_type,mapped_type>,set即为key_type

set<string>::key_type	//即为string
set<string>::value_type	//即为string
map<string,int>::key_type	//即为string
map<string,int>::mapped_type	//即为int
map<string,int>::value_type	//即为pair<const string,int>

迭代器

与顺序容器一样,但set中迭代器为const,map不能改变键值。

map<std::string,int> m_map;
m_map.begin()	//获取容器中首个元素的迭代器
m_map.cbegin()	//获取const类型的迭代器,同理cend()。
m_map.end()	//获取容器中最后一个元素的==下一位==的迭代器

//遍历容器
auto m_iterator=m_map.cbegin();
while(m_iterator!=m_map.end())
{
	std::cout<<m_iterator->first<<m_iterator->second<<std::endl;
	m_iterator++;
}

添加元素

使用insert方法,如插入一个map:

std::map<std::string,int> m_map;
m_map.insert({"Ha",5});

还可以向insert中传递两个迭代器,表示将两个迭代器中间的值都插入容器(按之前说明的比较方法)。
不含重复关键字的容器来说,单个插入的insert将返回一个pair类型,其first成员为一个迭代器,指向具有该关键字的元素,second成员为一个bool类型,表示该元素是否本就存在于容器中。
允许包含重复关键字的容器,单个插入的insert将返回一个迭代器,指向新元素的位置,不再返回bool值。因为对允许重复关键字来说,插入必然成功。

删除元素

关联容器定义了三个版本的迭代器,可以传入一个迭代器,指定要删除的元素,或传入一个迭代器对,指定删除范围。这两个版本均返回void。
第三个版本为传入一个关联容器的key_type参数,将删除所有匹配的元素,返回被删除的元素的数量。

某一类型元素数量

使用count,如:

auto number=m_map.count();

访问对象

使用下标访问

注意不能对允许重复的关键字的map使用下标,因为对应元素将不止一个。此外set也不可以使用下标。若下标所指元素不存在,将在容器中创建该键值对,并且值默认初始化。但注意使用at则不同,如m_map.at(“Ee”);由于不存在该元素,将抛出out_of_range异常。
下标操作符返回类型为该map的mapped_type类型,为左值,故可以改变其值,

使用find访问

m_map.find("Ha");

find的返回类型是一个迭代器,若存在有这个键值的元素,则返回指向该元素的迭代器(对于允许重复关键字的容器,返回第一个关键字为给定参数的迭代器),若不存在这样的元素,则返回尾后迭代器,即m_map.end()。

指定边界访问

m_map.lower_bound(k)	//返回第一个关键字不小于k的迭代器
m_map.upper_bound(k)	//返回第一个关键字大于k的迭代器
m_map.equal_range(k)	//返回一个迭代器对的pair,表示关键字等于k的元素的范围,若不存在该元素,则两个迭代器均为m_map.end()

对multimap进行查找

//找出所有关键字为"Ha"的键值对
std::string searchType="Ha";
auto number=m_map.count();
auto m_iterator=m_map.find(searchType);
while(number)
{
	std::cout<<m_iterator->first<<m_iterator->second<<std::endl;
	m_iterator++;
	number--;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值