map 容器的详细总结

目录结构:

  • 1 map容器 构造和赋值
  • 2 map 容器 大小与交换
  • 3 map容器 插入和删除
  • 4 map 容器 查找和统计
  • 5 map 容器排序
  • 6 自定义数据类型排序例1-2
  • 7 关于重载运算符的基本理解
  • 8 判断map是否包含key

参考:65 map容器-构造和赋值_哔哩哔哩_bilibili

1 map容器 构造和赋值

map 中所有元素都是成对出现,插入数据时要使用对组 例如: map<int,int>; map<string,string>

#include <iostream>
using namespace std;
#include <map>
// map容器 构造和赋值

//打印map容器
void Printmap(map<int, int> &m) {
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) {
    // map<int,int>
    // 第一个int代表key,也可以用first表示,第二个int代表value,也可以用second表示
    cout << "key = " << (*it).first << " value = " << it->second << endl;
  }
    cout<<endl;//换行
}

void test01() {
  //创建map容器,模板参数列表要写两个,成对出现,一个代表key,起到索引的作用,一个代表value,起到实值的作用

  //默认构造
  map<int, int> m; 
  //往容器中插入数据,对组pair<int, int>  key=1,value=10;
  //map 会按照key值从小到大自动排序,即使1和2互换位置,也是从小到大排序输出
  m.insert(pair<int, int>(1, 10));
  m.insert(pair<int, int>(2, 20));
  m.insert(pair<int, int>(3, 30));
  m.insert(pair<int, int>(4, 40));

  Printmap(m);

  //拷贝构造
  map<int,int>m2(m);
  Printmap(m2);

  //赋值
  map<int,int> m3;
  m3 = m2;

  Printmap(m3);

}

int main() {
  test01();
  return 0;
}

2 map 容器 大小与交换

统计大小-> size()

判断是否为空-> empty()

交换容器->swap()

#include <iostream>
using namespace std;
#include <map>

// map容器 大小和交换

//打印map容器
void PrintMap(map<int, int> &m) {
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) {
    cout << "key = " << it->first << " value = " << it->second << endl;
  }
  cout << endl;
}

//大小
void test01() {
  map<int, int> m;

  m.insert(pair<int, int>(1, 10));
  m.insert(pair<int, int>(2, 20));
  m.insert(pair<int, int>(3, 30));

  if (m.empty()) {
    cout << "m 为空" << endl;
  } else {
    cout << "m 非空" << endl;
    cout << endl;
    cout << "m的大小:" << m.size() << endl;
  }
}

//交换

void test02() {
  map<int, int> m;

  m.insert(pair<int, int>(1, 10));
  m.insert(pair<int, int>(2, 20));
  m.insert(pair<int, int>(3, 30));

  map<int, int> m1;

  m1.insert(pair<int, int>(4, 40));
  m1.insert(pair<int, int>(5, 50));
  m1.insert(pair<int, int>(6, 60));

  cout << "交换前:" << endl;
  PrintMap(m);
  PrintMap(m1);

  m.swap(m1);
  cout << "互换后:" << endl;
  PrintMap(m);
  PrintMap(m1);
}

int main() {
  //   test01();
  test02();
  return 0;
}

3 map容器 插入和删除

  //[]不建议插入。用途:通过key 找到对应的value
  cout << m[4] << endl;

#include <iostream>
using namespace std;
#include <map>

//打印map容器
void PrintMap(map<int, int> &m) {
  for (map<int, int>::iterator it = m.begin(); it != m.end(); it++) {
    cout << "key = " << it->first << " value = " << it->second << endl;
  }
  cout << endl;
}

void test01() {
  map<int, int> m;

  //插入
  //第一种,对组模板形式
  m.insert(pair<int, int>(1, 10));

  //第二种,make_pair 制造对组,避免再写模板参数,直接写(key,value)
  m.insert(make_pair(2, 20)); //推荐使用

  //第三种
  m.insert(map<int, int>::value_type(3, 30)); //不推荐使用

  //第四种
  m[4] = 40; //不建议使用

  //[]不建议插入。用途:通过key 找到对应的value
  cout << m[4] << endl;

  cout << m[5] << endl; //此处会给你创建一个不存在的数,key=5,value=0

  PrintMap(m);
}

int main() {
  test01();
  return 0;
}

输出:

  //删除
  cout << "删除:" << endl;
  m.erase(m.begin()); //删除第一个元素
  PrintMap(m);

  m.erase(3); //按key删除,无法按照value删除
  PrintMap(m);

  //清空
  //   m.erase(m.begin(),m.end()); //按区间删除
  m.clear();
  PrintMap(m);

输出:


4 map 容器 查找和统计

注意:

find() 无论找到与否,返回的都是一个迭代器,查到则返回查到元素的迭代器,查不道返回的是end()的迭代器

map 不允许插入重复的key元素 ,count 统计结果要么是0,要么是1

multimap 的count统计可能大于1

#include <iostream>
using namespace std;
#include <map>
// map容器 查找和统计

void test() {
  //查找
  map<int, int> m;
  m.insert(make_pair(1, 10));
  m.insert(make_pair(2, 20));
  m.insert(make_pair(3, 30));
  m.insert(make_pair(3, 40)); //此处插入失败
  map<int, int>::iterator pos =
      m.find(2); // find() 无论找到与否,返回的都是一个迭代器,查到则返回查到元素的迭代器,查不道返回的是end()的迭代器
  if (pos != m.end()) {
    cout << " 查到元素key = " << (*pos).first << " value = " << pos->second
         << endl;
  } else {
    cout << "没有找到元素key" << endl;
  }

  //统计
  // map 不允许插入重复的key元素 ,count 统计结果要么是0,要么是1
  // multimap 的count统计可能大于1
  int num = m.count(2);
  cout << "num = " << num << endl;
}

int main() {
  test();
  return 0;
}

 5 map 容器排序

利用仿函数可以指定map容器的排序规则

对于自定义的数据类型,map必须指定排序规则

#include <iostream>
using namespace std;
#include <map>

// map 容器的排序 默认从小到大排序

//仿函数
class mycompare {
public:
  //对两个数做对比操作 operator()重载运算符,() 参数列表
  bool operator()(int v1, int v2) {
    //降序
    return v1 > v2;
  }
};

void test() {
  //利用仿函数mycompare修改排序规则
  map<int, int,mycompare> m;   //mycompare可以按照自己的方式改变排序规则,大->小
  m.insert(make_pair(1, 10));
  m.insert(make_pair(2, 20));
  m.insert(make_pair(3, 30));
  m.insert(make_pair(4, 40));
  m.insert(make_pair(5, 50));
  for (map<int, int,mycompare>::iterator it = m.begin(); it != m.end(); it++) {
    cout << " key = " << it->first << " value = " << it->second << endl;
  }
}

int main() {
  test();
  return 0;
}

6 自定义数据类型排序例1

在C++中使用map进行自定义数据类型的排序可以通过重载小于运算符(<)来实现。下面是一个示例代码:

#include <iostream>
#include <map>
using namespace std;
 
// 自定义数据类型
struct Person {
    string name;
    int age;
};
 
bool operator<(const Person& p1, const Person& p2) {
参数列表需传入两个对象进行比较,const表示参数对象p1/p2不会被修改
    // 根据年龄从小到大排序
    return p1.age < p2.age;
}
 
int main() {
    // 创建一个存放Person对象的map
    map<Person, int> personMap;  //Person指的key,int 指的value
    
    // 添加元素到map
    Person p1 = {"Alice", 30};
    Person p2 = {"Bob", 25};
    Person p3 = {"Charlie", 40};
   //利用方式四插入数据
    personMap[p1] = 1;
    personMap[p2] = 2;
    personMap[p3] = 3;
    
    // 输出按照年龄排序后的结果
    for (auto it : personMap) {
        cout << "Name: " << it.first.name << ", Age: " << it.first.age << endl;
    }
    
    return 0;
}

这段代码首先定义了一个名为Person的自定义数据类型,包含两个成员变量name和age。然后我们重载了小于运算符operator<(),并指定了按照年龄从小到大排序的规则。接下来,我们创建了一个存放Person对象的map,将三个不同的人物对象作为key,分别关联上相应的值。最后,我们遍历打印出按照年龄排序后的结果。

6 自定义数据类型排序例2

#include <iostream>
#include <map>
using namespace std;
#include <string>
// 自定义数据类型
class Person {
public:
  Person(string name, int age) {
    this->m_name = name;
    this->m_age = age;
  }

  string m_name;
  int m_age;
};

//仿函数
class mycompare {
public:
  //对两个数做对比操作 operator()重载运算符,() 参数列表
  bool operator()(const Person &p1, const Person &p2) {
    //降序
    return p1.m_age > p2.m_age;
  }
};

void test() {
  map<Person, int, mycompare> p;//在int后面插入仿函数mycompare可以实现按自定义类型排序。

  //创建对象
  Person p1("liu", 25);
  Person p2("z", 27);
  Person p3("y", 29);
  //利用方式二插入数据
  p.insert(make_pair(p1, 1));
  p.insert(make_pair(p2, 2));
  p.insert(make_pair(p3, 3));

  auto it = p.find(p2);//获取指向p2对象的迭代器
  cout << "name:" << it->first.m_name << " age = " << it->first.m_age << endl; //打印p2对象的属性
  cout << "value:" << it->second << endl; //打印p2对象的value


  for (map<Person, int, mycompare>::iterator it = p.begin(); it != p.end();
       it++) {
    cout << " name " << it->first.m_name << " age = " << it->first.m_age
         << endl;
  }
}

int main() {

  test();

  return 0;
}

输出:


7 关于重载运算符的基本理解

详细参考:https://www.cnblogs.com/ECJTUACM-873284962/p/6771262.html

重载运算符概念基本理解:

 运算符函数重载一般有两种形式:重载为类的成员函数和重载为类的非成员函数。非成员函数通常是友元。(可以把一个运算符作为一个非成员、非友元函数重载。但是,这样的运算符函数访问类的私有和保护成员时,必须使用类的公有接口中提供的设置数据和读取数据的函数,调用这些函数时会降低性能。可以内联这些函数以提高性能。)

   

成员函数运算符

 运算符重载为类的成员函数的一般格式为:     <函数类型> operator <运算符>(<参数表>)     {      <函数体>     } 如:bool operator <(const node &a)const {

//<函数类型> bool ;   <运算符> 为 <(即小于号);<参数表> 为const node &a

}

  当运算符重载为类的成员函数时,函数的参数个数比原来的操作数要少一个(后置单目运算符除外),这是因为成员函数用this指针隐式地访问了类的一个对象,它充当了运算符函数最左边的操作数。因此:

(1) 双目运算符重载为类的成员函数时,函数只显式说明一个参数,该形参是运算符的右操作数。

(2) 前置单目运算符重载为类的成员函数时,不需要显式说明参数,即函数没有形参。

(3) 后置单目运算符重载为类的成员函数时,函数要带有一个整型形参。     调用成员函数运算符的格式如下:     <对象名>.operator <运算符>(<参数>)     它等价于     <对象名><运算符><参数>     例如:a+b等价于a.operator +(b)。一般情况下,我们采用运算符的习惯表达方式。

友元函数运算符

 运算符重载为类的友元函数的一般格式为:     friend <函数类型> operator <运算符>(<参数表>)     {      <函数体>     }

  当运算符重载为类的友元函数时,由于没有隐含的this指针,因此操作数的个数没有变化,所有的操作数都必须通过函数的形参进行传递,函数的参数与操作数自左至右一一对应。

 调用友元函数运算符的格式如下:     operator <运算符>(<参数1>,<参数2>)     它等价于     

<参数1><运算符><参数2>     例如:a+b等价于operator +(a,b)。

下面来进行这段代码的分析:

struct node {  //定义一个结构体node(节点)

   int x;

   int y;

   int len;   //node中有3个成员变量x,y,len

// operator <此处表示重载了小于的运算符

   bool operator <(const node &a)const {//重载<操作符。可以对两个node使用<操作符进行比较

       return len<a.len;

   }

};

括号中的const表示参数a对象不会被修改,最后的const表明调用函数对象不会被修改!

关系运算符重载

关系运算符有==,!=,<,>,<=,>=。

1     bool operator == (const A& ); 
2     bool operator != (const A& );
3     bool operator < (const A& );
4     bool operator <= (const A& );
5     bool operator > (const A& );
6     bool operator >= (const A& );

8 判断map是否包含key

在C++中,可以使用std::map容器来存储键值对,并使用find()函数来判断是否包含指定的键。

以下是两种实现方法:

方法一:

#include <iostream>
#include <map>
 
int main() {
    std::map<int, std::string> my_map = {{1, "apple"}, {2, "banana"}, {3, "orange"}};
    int key = 2;
 
    if (my_map.find(key) != my_map.end()) {
        std::cout << "The map contains the key." << std::endl;
    } else {
        std::cout << "The map does not contain the key." << std::endl;
    }
 
    return 0;
}

方法二:

#include <iostream>
#include <map>
 
int main() {
    std::map<int, std::string> my_map = {{1, "apple"}, {2, "banana"}, {3, "orange"}};
    int key = 2;
 
    auto it = my_map.find(key);  //find返回的是一个迭代器
    if (it != my_map.end()) {
        std::cout << "The map contains the key." << std::endl;
    } else {
        std::cout << "The map does not contain the key." << std::endl;
    }
 
    return 0;
}

总结:

        这两种方法都利用了find()函数,在std::map中查找指定的键。如果find()返回的迭代器指向end(),则说明map中不包含该键,否则就说明包含该键。

补充:

参考:C++判断map中key值是否存在_c++如何判断map中是否有某个key-CSDN博客

C++ map中key值存在情况判定
1、count函数
count函数用于统计key值在map中出现的次数,map的key不允许重复,因此如果key存在返回1,不存在返回0

if (testMap.count(key) == 0)
    cout << "no this key" << endl;

2、find函数
iterator find ( const key_type& key );

如果key存在,则find返回key对应的迭代器,如果key不存在,则find返回尾后迭代器end()。

if (testMap.find(key) == testMap.end())
    cout << "no this key" << endl;

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                    

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值