首页 > 其他分享 >关联容器(map、set、multimap、multiset、pair、unordered_map)

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

时间:2023-10-10 10:03:45浏览次数:36  
标签:map multimap word string 关键字 set const include


一、使用关联容器

key---value)对:关键字起到索引的作用,值则表示与索引相关联的数据。set中每个元素只包含一个关键字;set支持高效的关键字查询操作---检查一个关键字是否在set中。

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

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

    【Note】:

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

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

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>();
    }
}

 

    上述代码的运行结果如下:

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


二、关联容器操作

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;
}


    上述代码的运行结果如下:


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


三、一个应用关联容器的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。
	}
}


    上述代码的运行结果如下:


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



四、无序容器

    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");
}

标签:map,multimap,word,string,关键字,set,const,include
From: https://blog.51cto.com/u_6526235/7788101

相关文章

  • @GetMapping、@PostMapping、@PutMapping、@DeleteMapping 的区别?
    对于@GetMapping、@PostMapping、@PutMapping、@DeleteMapping,首先我们得谈到RESTFUL风格接口,常用的URL请求方式就包括了GET、POST、PUT、DELETE等:谈到@GetMapping、@PostMapping、@PutMapping、@DeleteMapping等注解,首先得讲到@RequestMaping:@RequestMaping主要是将HTTP请求映......
  • 分布式锁-实现原理(setnx,redisson)
         ......
  • 无涯教程-Meteor - Assets
    静态服务器assets位于应用程序内的private私有子文件夹中。在以下示例中,无涯教程将学习如何使用简单JSON文件中的数据。第1步-创建文件夹让无涯教程创建一个私有文件夹和该文件夹内的my-json.json文件,无涯教程将在命令提示符窗口中使用以下命令来执行此操作,但是,您也可以......
  • mapper.xml 返回map格式
    //DAO层List<Map<String,Object>>selectRecord(Map<String,Object>map);  //mapper层<selectid="selectUpCountByTime"parameterType="map"resultType="java.util.HashMap">SELECTcreate_byasusernam......
  • Map根据value排序取topN
    publicstaticvoidmain(String[]args){Map<String,Integer>map=newHashMap<>();/*for(inti=0;i<1000000;i++){intnextInt=newRandom().nextInt();map.put("A"+i,i*nextInt......
  • MDC (Mapped Diagnostic Context)
    MDC是org.slf4j包下的一个类,它的全称是MappedDiagnosticContext,我们可以认为它是一个线程安全的存放诊断日志的容器。MDC的底层是用了ThreadLocal来保存数据的。我们可以用它传递参数。例如现在有这样一种场景:我们使用RestTemplate调用远程接口时,有时需要在header中传递信息,......
  • Command "python setup.py egg_info" failed with error code 1
     D:\ProgramFiles\python_3_6_4>python-mpipinstall--upgradepipCacheentrydeserializationfailed,entryignoredCollectingpip Cacheentrydeserializationfailed,entryignored Downloadinghttps://files.pythonhosted.org/packages/a4/6d/6463d49a93......
  • angular使用from动态设置验证器(clearValidators、setValidators)
    原文链接:https://www.longkui.site/program/frontend/angularfrom/4787/0.背景调试一个angular的form表单,根据条件动态赋予表单的权限验证。主要介绍clearValidators和setValidators的用法。1.代码初始化代码:1234567891011121314151617181920212......
  • JAVA中使用map如何不改变原来顺序
    原文链接:https://www.longkui.site/program/java/java%e4%b8%ad%e4%bd%bf%e7%94%a8map%e5%a6%82%e4%bd%95%e4%b8%8d%e6%94%b9%e5%8f%98%e5%8e%9f%e6%9d%a5%e9%a1%ba%e5%ba%8f/4793/0.背景后台返回数据的时候,发现根据数据库预定义好的字段排序被改变了,于是顺着代码逻辑找下去,发现......
  • SQLSugar中Includes和Mapper的区别
    在SQLSugar中,Include和Mapper确实在处理过滤器方面有一些不同的行为。Include方法:当你使用Include方法来加载关联实体时,SQLSugar会忽略过滤器,不会将过滤器应用于加载的关联实体。这意味着无论你是否定义了过滤器,使用Include方法加载的关联实体都会被加载,而不受过滤器的影响。......