精华内容
下载资源
问答
  • c++ Map和题目

    2021-10-10 10:34:53
    c++ map 1.dev-c++ 使用c++11的设置方法 2.map基本用法 简介 构造: 函数原型 功能 map<T1, T2> mp; map默认构造函数。 map(const map &mp); 拷贝构造函数。 赋值:(可以写赋值等号=) ...

    c++ map

    1.dev-c++ 使用c++11的设置方法

    在这里插入图片描述

    2.map基本用法

    简介

    构造:

    函数原型功能
    map<T1, T2> mp;map默认构造函数。
    map(const map &mp);拷贝构造函数。

    赋值:(可以写赋值等号=)

    函数原型功能
    map& operator=(const map &mp);重载等号操作符。

    map是STL的一个关联容器,它提供一对一的映射。

    • 第一个可以称为关键字(key),每个关键字只能在map中出现一次;first
    • 第二个可能称为该关键字的值(value);second

    map以模板(泛型)方式实现,可以存储任意类型的数据,包括使用者自定义的数据类型。

    map內部的实现自建一颗红黑树,这颗树具有对数据自动排序的功能, ( 后面有个题目会见识到 )

    map和multimap区别:

    • map不允许容器中有重复key值元素
    • multimap允许容器中有重复key值元素

    使用步骤

    1.引入头文件#include<map>

    2.定义一个map

    这里只来一个简单的定义(样例) map<int, string> mymap;

    定义:map<类型1,类型2> 名字; 类型1,2可以是自定义类型,自定义类型的话有注意事项,下面会有介绍;

    这样就定义了一个map了,键值对就是int—>string,mymap里面的元素就是这样的键值对。

    3.使用

    遍历

    我们先不管怎么插入的,直接来看看遍历:

    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    int main()
    {
    	map<int, string> mymap;
    	//数组形式插入
    	mymap[1] = "田小锋";
    	mymap[0] = "田小锋二号";
    	mymap[-1] = "田小锋三号";
    	
    	//普通遍历
    	cout << "普通遍历\n";
        //嫌太长了,可以typedef map<int, string>::iterator Iter;起个别名
    	for (map<int, string>::iterator it = mymap.begin(); it != mymap.end(); it++ ) {
    		cout << it->first << "-->" << it->second << endl;
    	}
    	
    	cout << endl;
    	//c++11遍历
    	cout << "c++11遍历\n";
    	for(auto &temp : mymap ) {
    		cout << temp.first << "-->" << temp.second << endl;
    	}
    	
    	return 0;
    }
    

    在这里插入图片描述

    map的迭代器指向的是一个键值对,it->first 是key,it->second是value.

    插入

    根据上面的例子,可知,map是根据key来排序的( 所以我们的key一定要可以比较 )

    1.数组形式插入

    map<int, string> mymap;
    //数组形式插入
    mymap[1] = "田小锋";
    mymap[0] = "田小锋二号";
    mymap[-1] = "田小锋三号";
    mymap[1] = "txf"; //按顺序来这条语句会覆盖上面的"田小锋";
    
    
    map<string, string> mymap;
    //数组形式插入
    mymap["txf"] = "田小锋";
    mymap["txf02"] = "田小锋二号";
    mymap["txf03"] = "田小锋三号";
    mymap["txf"] = "txf"; //同理
    

    2.insert

    insert插入的是pair

    pair、map<template1, template2>::value_type()、make_pair()函数

    //看看make_pair函数
    template pair make_pair(T1 a, T2 b) { 
        return pair(a, b); 
    }
    //本质还是一个pair,
    //pair是将2个数据组合成一个数据,当有这样的需求时就可以使用pair,如stl中的map就是将key和value放在一起来保存
    //当一个函数需要返回2个数据的时候,可以选择pair。 pair的实现是一个结构体,
    
    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    
    typedef map<string, string>::value_type Value;
    int main()
    {
    	map<string, string> mymap;
    
    	//1
    	mymap.insert(pair<string,string>("txf","田小锋"));
    	mymap.insert(pair<string,string>("txf1","田小锋1"));
    	mymap.insert(pair<string,string>("txf11","田小锋2"));
    	mymap.insert(pair<string,string>("txf0","田小锋3"));
    	
    	//2
    	mymap.insert(map<string, string>::value_type("txf007","小锋007"));
    	mymap.insert(map<string, string>::value_type("txf007","小锋007"));//不生效,key重复
    	mymap.insert(map<string, string>::value_type("txf007","小锋008888"));//insert不会更新key相同的
    	
    	mymap.insert(Value("txfqwer","小锋玩亚索"));//看上面起的别名
    
    	//3
    	mymap.insert(make_pair("txfnb","小锋牛逼"));
        
    	//普通遍历
    	cout << "普通遍历\n";
        //嫌太长了,可以typedef map<int, string>::iterator Iter;起个别名
    	for (map<string, string>::iterator it = mymap.begin(); it != mymap.end(); it++ ) {
    		cout << it->first << "-->" << it->second << endl;
    	}
    
    	cout << endl;
    	//c++11遍历
    	cout << "c++11遍历\n";
    	for(auto &temp : mymap ) {
    		cout << temp.first << "-->" << temp.second << endl;
    	}
    
    	return 0;
    }
    

    3.插入自定义类型

    前面说了,自定义类型的时候,key一定要能比较,先来看不比较的,value是我们自定义的数据类型

    //例子一
    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    
    typedef struct{
    	int no;
    	string name;
    }MyType;
    
    int main()
    {
    	map<int, MyType> mymap;
    
    	MyType a{1,"田小锋"};
    	mymap[1] = a;
    
    	cout << "c++11遍历\n";
        /*
        value是一个结构体,没有重写<<运算符,所以目前这个例子只能这么写
        */
    	for(auto &temp : mymap ) {
    		cout << temp.first << "-->" << temp.second.no <<":" << temp.second.name << endl;
    	}
    
    	return 0;
    }
    
    
    //下面是重写了<<运算符的,可以略过不看哈,重写<<运算符
    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    
    class MyType
    {
    	public:
    		MyType(){no = 0, name="";}
    		MyType(int no, string name){
    			this->no = no;
    			this->name = name;
    		}
    		int getNo() {
    			return no;
    		}
    		string getName() {
    			return name;
    		}
    		
    		friend ostream& operator<< (ostream &out, MyType &p ) {
    			out << p.getNo() << ":" << p.getName();
    			return out;
    		}
    	private:
    		int no;
    		string name;
    };
    
    int main()
    {
    	map<int, MyType> mymap;
    
    	MyType a(1,"田小锋"), b(2,"田小锋二号");
    	
    	mymap[1] = a;
    	mymap[2] = b;
    	mymap.insert(make_pair(3, MyType(3,"田小锋三号")));
    
    	cout << "c++11遍历\n";
    	for(auto &temp : mymap ) {
    		cout << temp.first << "-->" << temp.second << endl;
    	}
    
    	return 0;
    }
    

    在这里插入图片描述

    这里来说说当我们的key是自定义类型的时候:

    重写<运算符,经验之谈就别问为什么了

    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    
    //定义了一个结构体
    typedef struct{
    	int a;
    }Myint;
    
    //前面说了,key默认是排序的,这里我写的是l.a 如果 > r.a
    //就返回true,说明key大的排在了前面
    bool operator < (const Myint l, const Myint r ) {
    	return l.a > r.a;
    }
    
    int main()
    {
    	map<Myint, string> mymap;
    	Myint t0 = {1};
    	Myint t1 = {2};
    	Myint t2 = {3};
    	mymap[t0] = "田小锋0";
    	mymap[t1] = "田小锋1";
    	mymap[t2] = "田小锋2";
    	
    	cout << "c++11遍历\n";
    	for(auto &temp : mymap ) {
    		cout << temp.first.a << "-->" << temp.second << endl;
    	}
    
    	return 0;
    }
    
    typedef struct myint{
    	int a;
    	bool operator< ( const myint &r) {
    		return a > r.a;
    	}
    }Myint;
    
    上面的例子这样重写会报错,[Error] passing 'const myint' as 'this' argument of 'bool myint::operator<(myint)' discards qualifiers [-fpermissive]
    大意是:将'const myint'作为'bool myint::operator<(myint)''this'参数传递将丢弃限定符[-fppermissive]
        
    源码这样的:
        /// One of the @link comparison_functors comparison functors@endlink.
        template<typename _Tp>
        struct less : public binary_function<_Tp, _Tp, bool>
        {
            bool
                operator()(const _Tp& __x, const _Tp& __y) const  //注意这里,const限定符
            { return __x < __y; }
        };
    
    所以上面要这么写:
    typedef struct myint{
    	int a;
    	bool operator< ( const myint &r) const {
    		return a > r.a;
    	}
    }Myint;
    
    我反正是这么理解的,可能有不对之处,望大家指出来。
    

    上面演示的是结构体,类类型的话就跟这个差不多了,我就不演示了,下面抄一个别人的,定义一个类来重写比较自定义类型的

    typedef struct tagStudentInfo
    {
        int nID;
        string strName;
        
    }StudentInfo,*PStudentInfo;
    class sort
    {
    public:
        bool operator()(tagStudentInfo const &_A,tagStudentInfo const &_B) const
        {
            if(_A.nID<_B.nID) 
                return true;
            return false;
        }
    }
    int main()
    {
        map<StudentInfo,int,sort> mapStudent;
        StudentInfo studentInfo;
        studentInfo.nID=1;
        studentInfo.strName="student_one";
        mapStudent.insert(pair<StudentInfo, int>(studentInfo,80));
        return 0;
    }
    //选自CSDN 小C博客
    

    总结:自定义类型左key一定要能比较,即重写<运算符!!!!

    判断是否插入成功,我这里偷个懒:

    在这里插入图片描述

    查找

    1.count

    传入key,查看key的个数,(很明显有就是只有一个,map的key不能重复)

    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    
    int main()
    {
    	map<string, string> mymap;
    	
    	mymap["t0"] = "田小锋0";
    	mymap["t1"] = "田小锋1";
    	mymap["t2"] = "田小锋2";
    	
        //有就是1,没有就是0
    	int i = mymap.count("t0"), j = mymap.count("45");
    	cout << i << "\n" << j << endl;
    
    	return 0;
    }
    

    2.find

    定位到key出现的位置,该方法返回一个迭代器。
    当数据找到时,返回数据所在位置的迭代器;
    否则,返回的迭代器等于end方法返回的迭代器。

    在这里插入图片描述

    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    typedef map<string, string>::iterator MapIt;
    int main()
    {
    	map<string, string> mymap;
    	
    	mymap["t0"] = "田小锋0";
    	mymap["t1"] = "田小锋1";
    	mymap["t2"] = "田小锋2";
    	
    //    MapIt it = mymap.find("t4");
    	MapIt it = mymap.find("t0");
    	if ( it != mymap.end() ) cout << "找到了" << it->first << "->" << it->second << endl;
    	else cout << "找不到\n";
    	return 0;
    }
    
    删除

    erase

    在这里插入图片描述

    三种形式:传入key根据key删除; 根据迭代器删除; 根据迭代器的区间删除;

    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    typedef map<string, string>::iterator MapIt;
    int main()
    {
    	map<string, string> mymap;
    	
    	mymap["t0"] = "田小锋0";
    	mymap["t1"] = "田小锋1";
    	mymap["t2"] = "田小锋2";
    	mymap["t3"] = "田小锋3";
    	mymap["t4"] = "田小锋4";
    	
    	//key
    	mymap.erase("t0");
    	int i = mymap.erase("t5");//找不到,所以i为0
    	cout << i << endl;
    	
    	for (auto &temp : mymap ) {
    		cout << temp.first << "->" << temp.second << endl;
    	}
    	return 0;
    }
    
    //迭代器删除
    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    typedef map<string, string>::iterator MapIt;
    int main()
    {
    	map<string, string> mymap;
    	
    	mymap["t0"] = "田小锋0";
    	mymap["t1"] = "田小锋1";
    	mymap["t2"] = "田小锋2";
    	mymap["t3"] = "田小锋3";
    	mymap["t4"] = "田小锋4";
    	//下面的会异常,因为找不到,
    	//it指向的是end(),没有元素
    //	MapIt it = mymap.find("t5");
    //	mymap.erase(it);
    	MapIt it = mymap.find("t0");
        if ( it != mymap.end()) //判断一下就行了,t0肯定是能找到的
    		mymap.erase(it);
    	
    	for (auto &temp : mymap ) {
    		cout << temp.first << "->" << temp.second << endl;
    	}
    	return 0;
    }
    
    //区间删除
    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    typedef map<string, string>::iterator MapIt;
    int main()
    {
    	map<string, string> mymap;
    	
    	mymap["t0"] = "田小锋0";
    	mymap["t1"] = "田小锋1";
    	mymap["t2"] = "田小锋2";
    	mymap["t3"] = "田小锋3";
    	mymap["t4"] = "田小锋4";
    
    	MapIt s = mymap.find("t1");
    	MapIt e = mymap.find("t3");
    	//c++传统,左闭右开
    	mymap.erase(s,e);  //区间是[位置s,位置e),
    	
    	for (auto &temp : mymap ) {
    		cout << temp.first << "->" << temp.second << endl;
    	}
    	return 0;
    }
    
    总结常用方法:
    方法用途
    insert()插入元素,返回一个东西,我没写
    find()查找元素,返回迭代器
    count()查找个数
    erase()删除元素,key,迭代器
    size()返回元素个数
    empty()判断map是否为空
    begin()返回开始的迭代器
    end()返回最后一个元素后面的迭代器
    swap();交换两个map
    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    typedef map<string, string>::iterator MapIt;
    //交换
    int main()
    {
    	map<string, string> mymap0, mymap2;
    	
    	mymap0["t0"] = "田小锋0";
    	mymap2["t2"] = "田小锋2";
    	mymap0.swap(mymap2);
    	
    	cout << "mymap0\n";
    	for (auto &temp : mymap0 ) {
    		cout << temp.first << "->" << temp.second << endl;
    	}
    	
    	cout << "mymap2\n";
    	for (auto &temp : mymap2 ) {
    		cout << temp.first << "->" << temp.second << endl;
    	}
    	return 0;
    }
    

    题目实战:

    1.pta数据结构与算法:

    实现QQ新帐户申请和老帐户登陆的简化版功能。最大挑战是:据说现在的QQ号码已经有10位数了。

    输入格式:

    输入首先给出一个正整数N(≤105),随后给出N行指令。每行指令的格式为:“命令符(空格)QQ号码(空格)密码”。其中命令符为“N”(代表New)时表示要新申请一个QQ号,后面是新帐户的号码和密码;命令符为“L”(代表Login)时表示是老帐户登陆,后面是登陆信息。QQ号码为一个不超过10位、但大于1000(据说QQ老总的号码是1001)的整数。密码为不小于6位、不超过16位、且不包含空格的字符串。

    输出格式:

    针对每条指令,给出相应的信息:

    1)若新申请帐户成功,则输出“New: OK”;
    2)若新申请的号码已经存在,则输出“ERROR: Exist”;
    3)若老帐户登陆成功,则输出“Login: OK”;
    4)若老帐户QQ号码不存在,则输出“ERROR: Not Exist”;
    5)若老帐户密码错误,则输出“ERROR: Wrong PW”。

    输入样例:

    5
    L 1234567890 myQQ@qq.com
    N 1234567890 myQQ@qq.com
    N 1234567890 myQQ@qq.com
    L 1234567890 myQQ@qq
    L 1234567890 myQQ@qq.com
    

    输出样例:

    ERROR: Not Exist
    New: OK
    ERROR: Exist
    ERROR: Wrong PW
    Login: OK
    
    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    
    map<string, string> mydata;
    int n;
    string qq, pwd;
    
    char choice;
    
    int main()
    {
    	cin >> n;
    	while (n--) {
    		cin >> choice >> qq >> pwd;
    		if ( choice == 'L' ) {
    			if ( mydata.count(qq) == 0 ) {
    				cout << "ERROR: Not Exist\n";
    			}
    			else {
    				if ( mydata[qq] != pwd ) {
    					cout << "ERROR: Wrong PW\n";
    				}
    				else {
    					cout << "Login: OK\n";
    				}
    			}
    		}
    		else {
    			if ( mydata.count(qq) == 1 ) {
    				cout << "ERROR: Exist\n";
    			}
    			else {
    				cout << "New: OK\n";
    				pair<string,string> p(qq, pwd);
    				mydata.insert( p );
    			}
    		}
    	}
    	return 0;
    }
    
    
    2.洛谷寄包柜

    题目描述

    超市里有 n(n≤10^5)个寄包柜。每个寄包柜格子数量不一,第 i 个寄包柜有 ai(ai≤10^5)个格子,不过我们并不知道各个 ai 的值。对于每个寄包柜,格子编号从 1 开始,一直到 ai。现在有 q(q≤10^5) 次操作:

    • 1 i j k:在第 i个柜子的第 j 个格子存入物品 k(0≤k≤10^9)。当 k=0时说明清空该格子。
    • 2 i j:查询第 i 个柜子的第 j个格子中的物品是什么,保证查询的柜子有存过东西。

    已知超市里共计不会超过 10^7个寄包格子,ai 是确定然而未知的,但是保证一定不小于该柜子存物品请求的格子编号的最大值。当然也有可能某些寄包柜中一个格子都没有。

    输入格式

    第一行 2 个整数 n 和 q,寄包柜个数和询问次数。

    接下来 q 个整数,表示一次操作。

    输出格式

    对于查询操作时,输出答案。

    输入输出样例

    输入 #1

    5 4
    1 3 10000 114514
    1 1 1 1
    2 3 10000
    2 1 1
    

    输出 #1

    114514
    1
    
    #include <bits/stdc++.h>
    #include <cstdio>
    using namespace std;
    map<int,int> m[100005];
    int main()
    {
    	int n, q, c, a, b, num;
    	cin >> n >> q;
    	while ( q-- ) {
    		cin >> c >> a >> b;
    		if ( c == 1 )
    		{
    			cin >> num;
    			m[a][b] = num;
    		}
    		else {
    			cout << m[a][b] << '\n';
    		}
    	}
    	return 0;
    }
    

    看图就知道了:(map查找是很快的),一维map就是一个红黑树,二维map就是下图这样的嘛,差不多是这个样子。

    在这里插入图片描述

    展开全文
  • C++ map转为vector

    2021-11-05 15:27:17
    map<string,int> nmap; 直接在初始化vector时传入map的迭代器 vector<PAIR> vec(nmap.begin(),nmap.end()); //map按值排序 #include <iostream> #include <string> #include <...

    map<string,int> nmap; 

    直接在初始化vector时传入map的迭代器

    vector<PAIR> vec(nmap.begin(),nmap.end());

    //map按值排序
    #include <iostream>
    #include <string>
    #include <vector>
    #include <map>
    #include <algorithm>
    using namespace std;
     
    typedef pair<string, int> PAIR;  
     
    int cmp(const PAIR& x, const PAIR& y)//针对PAIR的比较函数
    {  
        return x.second > y.second;  //从大到小
    }  
     
    int main() {  
      map<string,int> nmap; 
     
      nmap["LiMin"] = 90;  
      nmap["ZiLinMi"] = 79;  
      nmap["BoB"] = 92;  
      nmap.insert(make_pair("Bing",99));  
      nmap.insert(make_pair("Albert",86));  
      //把map中元素转存到vector中   
      vector<PAIR> vec(nmap.begin(),nmap.end());
      sort(vec.begin(), vec.end(), cmp); //排序
      
      for (size_t i = 0; i != vec.size(); ++i) {  //输出
           cout << vec[i].first <<" "<<vec[i].second<<endl;  
      }  
     
      return 0;  
    }

     

    展开全文
  • map> #include <utility>//用pair所需要的头文件 using namespace std; int main() { map<string,int>v; int i; v.insert(make_pair("Tom",1)); v.insert(make_pair("Lily",2)); v.insert(make_...
    #include <iostream>
    #include <map>
    #include <utility>//用pair所需要的头文件
    using namespace std;
    int main()
    {
       map<string,int>v;
       int i;
       v.insert(make_pair("Tom",1));
       v.insert(make_pair("Lily",2));
       v.insert(make_pair("Tom",4));//插入无效
       cout<<v["Tom"]<<endl;
       cout<<v["Lily"]<<endl;
       v["Tom"]=3;
       cout<<v["Tom"]<<endl;
       if(v.count("Tom"))//用count判断有没有这个关键字,如果用if(关键字)判断当这个关键字对应的value是0时,就会出错
       {
           cout<<"7"<<endl;
       }
       else
       {
           cout<<"8"<<endl;
       }
        return 0;
    }
    

    遍历map:(与遍历set相似)
    按关键字大小从小到大遍历

    #include <iostream>
    #include <map>
    #include <utility>
    using namespace std;
    int main()
    {
       map<string,int>v;
       int i;
       v.insert(make_pair("Tom",3));
       v.insert(make_pair("Lily",2));
       v.insert(make_pair("Lisa",1));
       for(map<string,int>::iterator it=v.begin();it!=v.end();it++)
       {
           cout<<it->first<<"->"<<it->second<<endl;
       }
        return 0;
    }
    

    例题:
    蒜头君有个学霸同学,家中藏书可真谓汗牛充栋。小明想考一考学霸,给学霸出了一道难题。小明问这么多书籍,到底有多少本不一样的书,每样书的名字是什么?(因为有的书名是一样的,所以我们把它们视为同样的书)学霸就是学霸,张口就说出了答案。不知道你是否也是学霸?一起来挑战下?、
    输入格式
    第一行是书籍总量n(1<=n<=10^6)
    然后有n行书名(书名是一个英文字符串,字符串的长度小于100,中间没有空格)
    输出格式
    第一行是不同书籍的数量,然后按照书名的字典序输出书名和数量。
    样例输入:
    4
    English
    Math
    Chinese
    Chinese
    样例输出:
    3
    Chinese 2
    English 1
    Math 1

    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    map<string,int>shu;
    int main()
    {
        int n,i;
        string name;
        cin>>n;
        for(i=0;i<n;i++)
        {
            cin>>name;
            shu[name]++;
        }
        cout<<shu.size()<<endl;
        for(map<string,int>::iterator it=shu.begin();it!=shu.end();it++)
        {
            cout<<it->first<<' '<<it->second<<endl;
        }
        return 0;
    }
    

    例题:
    给定n个整数,求里面出现次数最多的数,如果有多个重复出现的数,求出值最大的那一个。当时给蒜头君难住了,现在蒜头君来考考你。
    输入格式:
    第一行输入一个整数n(1<=n<=100000),接下来一行输入n给int范围内的整数。
    输出格式:
    输出出现次数最多的数和出现的次数,中间用一个空格隔开,如果有多个重复出现的数,输出值最大的那个
    样例输入1:
    5
    1 1 2 3 4
    样例输出1:
    1 2
    样例输入2:
    10
    9 10 27 4 9 10 3 1 2 6
    样例输出2:
    10 2

    #include <iostream>
    #include <map>
    using namespace std;
    map<int,int>h;
    int main()
    {
        int n,i,a,maxv,cs=0;
        cin>>n;
        for(i=0;i<n;i++)
        {
            cin>>a;
            h[a]++;
        }
        for(map<int,int>::iterator it=h.begin();it!=h.end();it++)
        {
            if((it->second)>=cs)
            {
                cs=it->second;
                maxv=it->first;
            }
        }
        cout<<maxv<<' '<<cs<<endl;
        return 0;
    }
    

    map套set:
    (同班同学没有重名的情况)

    #include <iostream>
    #include <map>
    #include <set>
    using namespace std;
    int main()
    {
       map<int,set<string> >v;
       v[2].insert("Tom");
       v[1].insert("Sandy");
       v[3].insert("lll");
       if(v[2].count("Tom"))
       {
           cout<<"7"<<endl;
           v[2].erase("Tom");
       }
       else
       {
           cout<<"8"<<endl;
       }
       for(map<int,set<string> >::iterator it1=v.begin();it1!=v.end();it1++)
       {
           for(set<string>::iterator it2=it1->second.begin();it2!=it1->second.end();it2++)
           cout<<*it2<<"->"<<it1->first<<endl;
       }
        return 0;
    }
    
    

    map套map:
    (同班同学有重名的情况)

    #include <iostream>
    #include <map>
    #include <string>
    using namespace std;
    int main()
    {
        map<int,map<string,int> > v;
        int n,i;
        int classw;
        string name;
        cin>>n;
        for(i=0;i<n;i++)
        {
            cin>>classw>>name;
            v[classw][name]++;
        }
        for(map<int,map<string,int> >::iterator it1=v.begin();it1!=v.end();it1++)
        {
            for(map<string,int>::iterator it2=it1->second.begin();it2!=it1->second.end();it2++)
            {
                cout<<"There are "<<it2->second<<" people named "<<it2->first<<" in class "<<it1->first<<endl;
            }
        }
        return 0;
    }
    

    注意:map套set的时候输出当然不会有it2->firstit2->second具体输出什么视情况而定,不要死记

    展开全文
  • C++map容器可以建立映射,如果key使用自定义类,需要重载operator<运算符,但是由于find方法使用operator<来完成, 因此常常会遇到意想不到的意外。尽管有人说可以通过std::find_if通过重载operator==运算来...

    C++的map容器可以建立映射,如果key使用自定义类,需要重载operator<运算符,但是由于find方法使用operator<来完成, 因此常常会遇到意想不到的意外。尽管有人说可以通过std::find_if通过重载operator==运算来保证可靠查找,但是也会遇到意想不到的意外。

    以下的代码中,几种方法在find时均会遇到意想不到的意外,无法可靠find相应的key。

    //
    // Created by Denlee on 21-12-5.
    //
    
    #include <map>
    #include <iostream>
    #include <algorithm>
    #include <assert.h>
    
    class Point {
    private:
        int _x, _y;
    
    public:
        Point();
        Point(int x, int y);
        Point(const Point &pt);
        ~Point();
        Point &operator=(const Point &pt);
        bool operator==(const Point &pt) const;
        // partial order
        bool operator<(const Point &pt) const;
    
        friend std::ostream &operator<<(std::ostream &out, const Point &pt);
    };
    
    Point::Point() {
        _x=_y=0;
    }
    
    Point::Point(int x, int y) {
        _x = x; _y = y;
    }
    
    Point::Point(const Point &pt) {
        _x = pt._x;
        _y = pt._y;
    }
    
    Point::~Point() {
    
    }
    
    Point& Point::operator=(const Point &pt) {
        if(this != &pt) {
            this->_y = pt._y;
            this->_x = pt._x;
        }
        return *this;
    }
    
    bool Point::operator==(const Point &pt) const {
        return this->_x == pt._x && this->_y == pt._y;
    }
    
    bool Point::operator<(const Point &pt) const {
        return this->_x < pt._x || this->_y < pt._y;
    }
    
    std::ostream &operator<<(std::ostream &out, const Point &pt) {
        out << "(" << pt._x << "," << pt._y << ")";
        return out;
    }
    
    int main() {
        int i, j;
        int x = 10;
        int y = 9;
    
        std::map<Point, int> map_point;
        int order = 0;
        for(i=0; i<x; i++) {
            for(j=0; j<y; j++) {
                map_point.insert(std::pair<Point, int>(Point(i,j), order++));
            }
        }
        assert(map_point.size() == x * y);
    
        std::cout << "--------------find-----------------\n";
        for(i=0; i<x; i++) {
            for(j=0; j<y; j++) {
                std::map<Point, int>::const_iterator it;
                it = map_point.find(Point(i,j));
                if(it != map_point.end()) {
                    std::cout << it->first << ": " << it->second << "\n";
                } else {
                    std::cout << "(" << i << "," << j << ")\n";
                }
            }
        }
    
        std::cout << "-------------count------------------\n";
        for(i=0; i<x; i++) {
            for(j=0; j<y; j++) {
                Point pt(x,y);
                if(map_point.count(pt)) {
                    std::cout << pt << ": " << map_point[pt] << "\n";
                } else {
                    std::cout << "(" << i << "," << j << ")\n";
                }
            }
        }
    
        std::cout << "---------------find_if----------------\n";
        for(i=0; i<x; i++) {
            for(j=0; j<y; j++) {
                Point pt(x,y);
                std::map<Point,int>::iterator it = std::find_if(map_point.begin(),map_point.end(),[pt](std::pair<Point,int> obj){return obj.first == pt; });
                if(it  != map_point.end()) {
                    std::cout << it->first << ": " << it->second << "\n";
                } else {
                    std::cout << "(" << i << "," << j << ")\n";
                }
            }
        }
    
        std::cout << "-------------enumerate------------------\n";
        for(const auto& v : map_point) {
            std::cout << v.first << ": " << v.second << "\n";
        }
    
        return 0;
    }
    
    

    对于自定义类作为key,最好使用std::string来表征,并通过自定义比较函数来实现可靠查找.

    // Point类增加成员函数
    std::string to_string() const;
    
    std::string Point::to_string() const {
        return std::to_string(_x) + std::to_string(_y);
    }
    
    // 自定义比较函数
    class point_key_comp {
    public:
        bool operator()(const Point& pt1, const Point& pt2)const {
            return pt1.to_string() < pt2.to_string();
        }
    };
    
    //.....
    //使用Point类型作为map的key
    std::map<Point, int, point_key_comp> map_point;

    参考资料:

    [1] C++ STL: map自定义键值类型. C++ STL: map自定义键值类型_爱吃柚子的好奶罐-CSDN博客_c++ map 自定义类.

    [2] C++ 自定义比较函数(map和multimap)详解. C++ 自定义比较函数(map和multimap)详解.

    [3] C++中set/unordered_set 自定义比较规则. C++中set/unordered_set 自定义比较规则_nepu_bin的博客-CSDN博客.

    [4] C++ STL无序容器自定义哈希函数和比较规则(超级详细). C++ STL无序容器自定义哈希函数和比较规则(超级详细).

    展开全文
  • C++ map的简单实现

    千次阅读 热门讨论 2021-05-20 17:21:38
    map和set的底层都是通过红黑树来实现的,但并不是原生态的红黑树,而是经过改造后的红黑树。且容器都会在各自的类中添加一些独特的函数来解决各自适配的问题 map和set底层是改造后的红黑树,我们先来看看改造后的...
  • c++ map查找key

    2021-07-07 12:01:24
    1、在map中,由key查找value时,首先要判断map中是否包含key。 2、如果不检查,直接返回map[key],可能会出现意想不到的行为。如果map包含key,没有问题,如果map不包含key,使用下标有一个危险的副作用,会在map中...
  • 1,map简介 map是STL的一个关联容器,它提供一对一的hash。 第一个可以称为关键字(key),每个关键字只能在map中出现一次;第二个可能称为该关键字的值(value); map以模板(泛型)方式实现,可以存储任意类型的数据...
  • C++ map详解

    2020-12-19 14:53:48
    C++中,map提供的是一种键值对容器,第一个值为key,第二个值为value,有时候建立一个map会起到事半功倍的效果。 2.map的使用 (1)需要导入头文件 #include (2)map对象是一个模版类,需要关键字和存储对象两个...
  • 1、map的作用 可以实现各种类型的映射。可以用数组来类比,都是由下标和值组成,但数组用法很局限,下标不能是负数,而且开数组需要消耗太多的内存,开到10^7就内存超限了。因此,很多时候都用高级的map类或vector类...
  • C++ map与unordered_map区别及使用map与unordered_map区别1. 引入的头文件不同2. 内部实现机理不同3. 优缺点以及适用处map与unordered_map使用参考 文章转自: ...
  • C++ map值为结构体的示例

    千次阅读 2020-12-27 14:35:08
    某一种数据,会有重复记录,后附加各类数据。利用map的唯一性,将重复者过滤。并将附加的数据存储到结构体,方便在代码中使用。后续可写入文件或数据。
  • C++ map用法

    2020-12-22 19:56:25
    C++map 提供的是一种键值对容器,里面的数据都是成对出现的,如下图:每一对中的第一个值称之为关键字(key),每个关键字只能在 map 中出现一次;第二个称之为该关键字的对应值。在一些程序中建立一个 map 可以起...
  • C++ map 循环遍历删除

    2021-02-19 09:41:00
    map> #include <vector> #include <fstream> #include <assert.h> #include <algorithm> using namespace std; int main() { map<int,int> m; m.insert(pair<int,int>(1,...
  • C++ map find()用法

    2021-06-21 15:43:23
    C++ map find()用法一级目录二级目录三级目录 https://vimsky.com/examples/usage/map-find-function-in-c-stl.html 一级目录 二级目录 三级目录
  • map> #include <vector> using namespace std; struct veh2url { string str_license="-1"; string str_id="-1"; string str_time="-1"; bool operator < (const veh2url &e).
  • C++map容器-大小和互换

    2021-01-31 00:10:06
    map大小和互换 功能描述: 统计map容器大小以及交换map容器 函数原型: 代码如下: #include <iostream> using namespace std; #include <map> //map容器 大小和交换 void test01() { map<int, ...
  • map中find()函数的参数是key,返回的是查找到位置的迭代器,如果找不到就返回end()位置的迭代器: vector<int> twoSum(vector<int>& nums, int target) { map<int, int> m; for (int i = ...
  • C++ map cend() 函数使用方法及示例C ++ map cend()函数用于返回常量迭代器,该常量迭代器位于map中的最后一个元素旁边。注意:- 这是一个占位符。此位置没有元素,尝试访问是未定义的行为。语法const_iteratorcend...
  • multimap<int, vector<Person>> m1; multimap<int, vector<Person>>::iterator it = m1.begin(); //如果要访问 vector<Person>::iterator ite1=it->...//这样就可以了
  • C++中使用map时可能会遇到重复insert同一个key的情况 这个时候新的值不会覆盖原有的值,而是会忽略这次insert 如果需要修改某个key的值,可以使用赋值的方式 map[key]=value
  • map通过值找键countfind通过键找值 通过值找键 count if (ans.count(key1)) //查键 cout << ans[key1] << endl; else cout << "what?" << endl; count():如果找到则为真 find ...
  • flyfish测试所需头文件#include #include #include #include 初始std::map t;t.insert(std::make_pair(1, "a"));t.insert(std::make_pair(2, "b"));t.insert(std::make_pair(3, "c"));t.insert(std::make_pair(4, "d...
  • C++ map的用法,哈希表

    2021-03-24 22:05:51
    map> map是一个键值对,前面是一个键后面对应一个值 map<int,int> mp; mp是哈希表的名称,int表示键为int型数值并且值也是int型 假如: map<string,string> mp; string name, phonenum; mp[name] = ...
  • c++map自动排序特性

    2021-01-29 20:09:37
    c++中的map会自动根据first值排序,这样排好序后输出第一个用begin,输出最后一个用rbegin first支持int和string类型的排序,其原理应该是ascii(这一点我没有考证,反正也不太重要) 举个栗子 题目描述 每天第...
  • 结论:不同的环境下表现是... map<int,int> mp; mp[1] = 1; mp[2] = 2; mp[3] = 3; auto it = mp.find(1); mp.erase(it); cout << it->second << endl; //Mac homebrew安装的g++ 11.2.0 :
  • map有key和value 如果用map,默认是按key排序 用unordered_map则不排序 那么如何按照value进行排序呢: 一个很简单的做法就是用vector存map的key和value,因为sort方法只能对vector等进行排序,可以对sort施加...
  • c++ map/字典 元素遍历

    2021-05-07 15:29:50
    #include <iostream> #include <map> using namespace std; int main() { map<int, int> _map; _map[0] = 1; _map[1] = 2; _map[10] = 10; map<int, int>::ite
  • C++map容器-插入和删除

    2021-01-31 00:11:02
    map插入和删除 功能描述: map容器进行插入数据和删除数据 函数原型: 代码如下: #include <iostream> using namespace std; #include <map> //map容器 插入和删除 void printMap(map<int, int>...
  • 1、map简介map是一类关联式容器。它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。对于迭代器来说,可以修改实值,而不能修改key。2、map的功能自动建立Key - value的...
  • map unordered_map

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 264,810
精华内容 105,924
关键字:

c++map

c++ 订阅