关联容器(map、set、multimap、multiset、pair、unordered_map)

一、使用关联容器

    关联容器支持高效的关键字查找和访问。两个主要的关联容器类型是map和set。map中的元素是一些关键字---值(key---value)对:关键字起到索引的作用,值则表示与索引相关联的数据。set中每个元素只包含一个关键字;set支持高效的关键字查询操作---检查一个关键字是否在set中

    multimap允许多个元素具有相同的关键字

    pair类型用于保存两个数据类型,pair的数据成员是public的。

    【Note】:

    1)定义一个map时,必须指明关键字类型和值类型;而定义set时,只需指定关键字类型

    2)一个map或者set中的关键字是唯一的,并且得到的值是按字典序排列的

    3)map的value_type是一个pair,但是关键字是const类型

#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <utility>//pair类型存在于该头文件中。
#include <string>
using namespace std;
using v_int = vector<int>;
using v_str = vector<string>;
pair<string,int> process(vector<string> &v);
int main(int argc, char const *argv[])
{

    /*************************
    *使用关联容器(map、set)。
    **************************/
    
    map<string,size_t> word_count;//空map,关键字是string,值是size_t类型。
    set<string> exclude = {"the","but"};//用set保存想忽略的单词。
    string word;
    while(cin >> word)
    {
        //find返回一个迭代器,如果关键字在set中,迭代器指向该关键字,否则返回尾迭代器。
        if(exclude.find(word) == exclude.end())//只统计不在exclude中的单词。
            ++word_count[word];//使用string作为下标,提取word的计数器并将其加一。
    }
    for (const auto &w : word_count)
    {
        //map使用的pair用first成员保存关键字,用second成员保存对应的值。
        cout << w.first << " occurs " << w.second << 
        ((w.second > 1) ? " times" : " time") << endl;
    }
    v_int vec;
    for (auto i=0 ; i!=10 ; ++i)
    {
        vec.push_back(i);
        vec.push_back(i);
    }
    set<int> iset(vec.cbegin(),vec.cend());
    multiset<int> miset(vec.cbegin(),vec.cend());//允许多个元素具有相同的初始值。
    cout << vec.size() << endl;
    cout << iset.size() << endl;
    cout << miset.size() << endl;

    /*****************************
    *pair类型(保存两个数据类型)。
    ******************************/

    string str;
    int a;
    vector<pair<string,int>> vec2;
    while(cin >> str >> a)
    {
        pair<string,int> p = {str,a};
        vec2.push_back(p);
    }
    for (const auto s : vec2)
    {
        cout << s.first << " " << s.second << endl;
    }
    v_str vstr = {"abc","ef"};
    auto p2 = process(vstr);
    cout << p2.first << " " << p2.second << " " << endl;

    system("pause");
    return 0;
}
pair<string,int> process(vector<string> &v)//创建pair对象的函数。
{
    if(!v.empty())
    {
        //返回最后一个元素,并得到其长度。
        return { v.back(),v.back().size() };//对返回值进行列表初始化。
    }
    else
    {
        return pair<string,int>();
    }
}
      上述代码的运行结果如下:



二、关联容器操作

1、关联容器操作(迭代器、遍历迭代器、insert、erase、下标操作、访问元素)

#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <utility>
#include <string>
using namespace std;
using v_int = vector<int>;
pair<string,int> process(vector<string> &v);
int main(int argc, char const *argv[])
{

	/***************************
	*关联容器迭代器、遍历迭代器。
	****************************/

	map<string,int> word_count = 
	{
		{"ABC",1},
		{"EDF",2}
	};
	//获得指向首元素的迭代器。
	auto map_it = word_count.cbegin();
	while(map_it != word_count.cend())
	{
		//解引用迭代器。
		cout << map_it->first << " occurs " << map_it->second << " times" << endl;
		++map_it;
	}

	/*******************
	*添加元素(insert)。
	********************/

	map<string,size_t> word_count2;
	string word;
	while(cin >> word)
	{
		auto ret = word_count2.insert({word,1});
		if(!ret.second)
			++(ret.first->second);//ret是一个pair类型,其第一个成员是一个map迭代器。
	}
	for (const auto &w : word_count2)
	{
		cout << w.first << " occurs " << w.second << " time" << endl;
	}
	//向multimap或者multiset中添加元素。
	multimap<string,string> authors;//一个关键字与多个元素相关联,比如一个作者出版的书。
	authors.insert({"Eric","DSP"});
	authors.insert({"Eric","convex"});
	authors.insert({"Eric","matrix"});
	for (const auto &w : authors)
	{
		cout << w.first << " " << w.second << endl;
	}

	/******************
	*删除元素(erase)。
	*******************/

	string removal_word = {"EDF"};
	if(word_count.erase(removal_word))//删除一个关键字返回删除的元素数量。
	{
		cout << removal_word << " removed!" << endl;
	}
	else
	{
		cout << removal_word << " not found!" << endl;
	}
	for (const auto &w : word_count)
	{
		cout << w.first << " occurs " << w.second << 
		((w.second > 1) ? " times" : " time") << endl;
	}

	/**************
	*map的下标操作。
	***************/

       word_count["EDF"] = 1;//插入一个关键字,并进行值初始化,如果是新的关键字就添加到map中。
	++word_count["EDF"];//返回值是一个左值,可读可写。
	cout << word_count["EDF"] << endl;

	/******************
	*访问元素(find、count、lower_bound、upper_bound)。
	*******************/
 
       set<int> iset = {1,4,5,6,7,8,9};
	iset.find(1);
	cout << iset.count(1) << endl;

	string search_author("Eric");//要查找的作者。
	auto entries = authors.count(search_author);//元素的数量。
	auto iter = authors.find(search_author);//此作者的第一本书。
	while(entries)
	{
		cout << iter->second << " ";//打印每个书名。
		++iter;
		--entries;
	}
	cout << endl;
	//lower_bound定位到第一个匹配的元素,upper_bound指向最后一个匹配的元素,如果两者相等,则无关键字。
	for (auto beg = authors.lower_bound(search_author),
		end = authors.upper_bound(search_author) ;
		beg != end ; ++beg)
	{
		cout << beg->second << " ";
	}
	cout << endl;
	for (auto pos = authors.equal_range(search_author) ;
		pos.first != pos.second ; ++pos.first)
	{
		cout << pos.first->second << " ";
	}

	system("pause");
	return 0;
}
    上述代码的运行结果如下:



三、一个应用关联容器的demo

    一个单词转换的map:给定一个string,按某种规则转换为另一个string,转换规则是用某些字母替换对应的短语。

#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <sstream>
using namespace std;
void word_transform(ifstream &map_file,ifstream &input,ofstream &out);
map<string,string> BuildMap(ifstream &map_file);
const string &transform(const string &s,const map<string,string> &m);
int main(int argc, char const *argv[])
{
	ifstream in("input.txt");
	ifstream trans("trans.txt");
	ofstream out("output.txt");
	word_transform(trans,in,out);
	system("pause");
	return 0;
}
//子函数输出到文件中,添加一个引用类型的参数即可。
void word_transform(ifstream &map_file,ifstream &input,ofstream &out)
{
	auto trans_map = BuildMap(map_file);//保存转换规则。
	string text;
	while(getline(input,text))//读取每一行输入。
	{
		istringstream stream(text);//string流输入。
		string word;
		bool firstword = true;
		while(stream >> word)//读取输入的每个单词。
		{
			if(firstword)
			{
				firstword = false;//控制是否打印空格。
			}
			else
			{
				out << " ";//打印单词间的一个空格。
			}
			out << transform(word,trans_map);//打印输出。
		}
		out << endl;
	}
}
map<string,string> BuildMap(ifstream &map_file)
{
	map<string,string> trans_map;
	string key;
	string value;
	//读取第一个单词存入key,剩余内容放在value中。
	while(map_file >> key && getline(map_file,value))
	{
		if(value.size() > 1)//检查是否有转换规则。
		{
			trans_map[key] = value.substr(1);//跳过前导的空格
		}
		else
		{
			throw runtime_error("no rule for" + key);
		}
	}
	return trans_map;
}
const string &transform(const string &s,const map<string,string> &m)
{
	auto map_it = m.find(s);//实际的转换规则。
	if(map_it != m.cend())//如果单词在转换规则中。
	{
		return map_it->second;//使用替换短语。
	}
	else
	{
		return s;//没有就返回原来的string。
	}
}
    上述代码的运行结果如下:


四、无序容器

    unordered_map是无序容器,关键字类型是无序的,使用hash函数和关键字类型的==运算符。

#include <iostream>
#include <map>
#include <unordered_map>
#include <string>
using namespace std;
int main(int argc, char const *argv[])
{
	//unordered_map是无序容器,关键字类型是无序的,使用hash函数和关键字类型的==运算符。
	unordered_map<string,size_t> word_count;
	string word;
	while(cin >> word)
	{
		++word_count[word];
	}
	for (const auto &w : word_count)
	{
		cout << w.first << " occurs " << w.second << 
		((w.second > 1) ? " times" : " time") << endl;
	}
	system("pause");
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

~青萍之末~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值