Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字(key),每个关键字只能在map中出现一次,第二个可能称为该关键字的值(value))的数据 处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程上提供快速通道。这里说下map内部数据的组织,map内部自建一颗红黑树(一 种非严格意义上的平衡二叉树),这颗树具有对数据自动排序的功能,所以在map内部所有的数据都是有序的(转);

特点:增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响。对于迭代器来说,可以修改实值,而不能修改key;

功能:

自动建立Key - value的对应。key 和 value可以是任意你需要的类型。

根据key值快速查找记录,查找的复杂度基本是Log(N)

头文件:#include<map>

数据的插入:

①:insert;

 map<int, string> mapStudent;  

    mapStudent.insert(pair<int, string>(, "student_one"));  

②:用insert函数插入value_type数据

 map<int, string> mapStudent;  

    mapStudent.insert(map<int, string>::value_type (, "student_one"));  

③:用数组方式插入数据

map<int, string> mapStudent;  

    mapStudent[] = "student_one";  

    mapStudent[] = "student_two";  

    mapStudent[] = "student_three";  

    map<int, string>::iterator iter;  

    for(iter = mapStudent.begin(); iter != mapStudent.end(); iter++)  

        cout<<iter->first<<' '<<iter->second<<endl;  

以上三种用法,虽然都可以实现数据的插入,但是它们是有区别的,当然了第一种和第二种在效果上是完成一样的,用insert函数插入数据,在数据的 插入上涉及到集合的唯一性这个概念,即当map中有这个关键字时,insert操作是插入数据不了的,但是用数组方式就不同了,它可以覆盖以前该关键字对应的值

Map的遍历

第一种:应用前向迭代器

第二种:应用反相迭代器,下放代码,正向就是rbegin改成begin,rend改成end;

int main()  

{  

    map<int, string> mapStudent;  

    mapStudent.insert(pair<int, string>(, "student_one"));  

    mapStudent.insert(pair<int, string>(, "student_two"));  

    mapStudent.insert(pair<int, string>(, "student_three"));  

    map<int, string>::reverse_iterator iter;  

    for(iter = mapStudent.rbegin(); iter != mapStudent.rend(); iter++)  

        cout<<iter->first<<"  "<<iter->second<<endl;  

}  

关于Map的sort的也从大牛的博客里copy来了解说,之前不会这种写法;

map中的元素是自动按Key升序排序,所以不能对map用sort函数;

这里要讲的是一点比较高深的用法了,排序问题,STL中默认是采用小于号来排序的,以上代码在排序上是不存在任何问题的,因为上面的关键字是int 型,它本身支持小于号运算,在一些特殊情况,比如关键字是一个结构体,涉及到排序就会出现问题,因为它没有小于号操作,insert等函数在编译的时候过 不去,下面给出两个方法解决这个问题。

第一种:小于号重载,程序举例。

#include <iostream>
#include <string>
#include <map>
using namespace std; typedef struct tagStudentinfo { int niD; string strName; bool operator < (tagStudentinfo const& _A) const { //这个函数指定排序策略,按niD排序,如果niD相等的话,按strName排序 if(niD < _A.niD) return true; if(niD == _A.niD) return strName.compare(_A.strName) < ; return false; } }Studentinfo, *PStudentinfo; //学生信息 int main() { int nSize; //用学生信息映射分数 map<Studentinfo, int>mapStudent; map<Studentinfo, int>::iterator iter; Studentinfo studentinfo; studentinfo.niD = ; studentinfo.strName = "student_one"; mapStudent.insert(pair<Studentinfo, int>(studentinfo, )); studentinfo.niD = ; studentinfo.strName = "student_two"; mapStudent.insert(pair<Studentinfo, int>(studentinfo, )); for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++) cout<<iter->first.niD<<' '<<iter->first.strName<<' '<<iter->second<<endl; return ;
}

第二种:仿函数的应用,这个时候结构体中没有直接的小于号重载,程序说明

/第二种:仿函数的应用,这个时候结构体中没有直接的小于号重载,程序说明  

#include <iostream>  

#include <map>  

#include <string>  

using namespace std;  

typedef struct tagStudentinfo  

{  

       int      niD;  

       string   strName;  

}Studentinfo, *PStudentinfo; //学生信息  

class sort  

{  

public:  

    bool operator() (Studentinfo const &_A, Studentinfo const &_B) const  

    {  

        if(_A.niD < _B.niD)  

            return true;  

        if(_A.niD == _B.niD)  

            return _A.strName.compare(_B.strName) < ;  

    return false;  

    }
}; int main() { //用学生信息映射分数 map<Studentinfo, int, sort>mapStudent; map<Studentinfo, int>::iterator iter; Studentinfo studentinfo; studentinfo.niD = ; studentinfo.strName = "student_one"; mapStudent.insert(pair<Studentinfo, int>(studentinfo, )); studentinfo.niD = ; studentinfo.strName = "student_two"; mapStudent.insert(pair<Studentinfo, int>(studentinfo, )); for (iter=mapStudent.begin(); iter!=mapStudent.end(); iter++) cout<<iter->first.niD<<' '<<iter->first.strName<<' '<<iter->second<<endl;
}

还有一些Map的函数就偷懒直接列下来了;

begin()          返回指向map头部的迭代器
  clear()         删除所有元素
      count()          返回指定元素出现的次数
      empty()          如果map为空则返回true
      end()            返回指向map末尾的迭代器
      equal_range()    返回特殊条目的迭代器对
      erase()          删除一个元素
      find()           查找一个元素
      get_allocator()  返回map的配置器
      insert()         插入元素
      key_comp()       返回比较元素key的函数
      lower_bound()    返回键值>=给定元素的第一个位置
      max_size()       返回可以容纳的最大元素个数
      rbegin()         返回一个指向map尾部的逆向迭代器
      rend()           返回一个指向map头部的逆向迭代器
      size()           返回map中元素的个数
      swap()            交换两个map  map中的swap不是一个容器中的元素交换,而是两个容器所有元素的交换。
      upper_bound()     返回键值>给定元素的第一个位置  
      value_comp()      返回比较元素value的函数

然后,今天写了一道有用到map的题,其实是用了map超级高效易懂;

以前写题目,遇到判断一个数是否出现过,都用flag[maxen]来进行存状态,但这只适用于数据范围较小的情况,若数据范围到1e9,那就GG了。今天在提示下想到用map,

建一个<long long,int>的map,first 表示该数是否出现过,int 代表出现几次;

不多说上题目;

Gym Two Sequences

You are given two sequences of integers AA and BB, and an integer kk.

Two sequences are equal if it is possible to rearrange one of the sequences such that each element in the sequence is equal to the corresponding element from the other sequence.

You can select one of the elements in sequence AA, and add to it any integer from the range [−k,k][−k,k]. Is it possible to make the two sequences equal by doing the specified operation exactly once?

Input

The first line of input contains a single integer TT, the number of test cases.

The first line of each case contains two space-separated integers nn and kk (1≤n≤1051≤n≤105)(1≤k≤1091≤k≤109), the length of each sequence and the number kk specified in the problem statement.

The next line contains nn space-separated integers (1≤Ai≤1091≤Ai≤109), the elements in sequence AA.

The next line contains nn space-separated integers (1≤Bi≤1091≤Bi≤109), the elements in sequence BB.

Output

For each test case, output a single line with YES if it is possible to make the two sequences equal in a single operation. Otherwise output NO.

Example

Input
3
3 2
1 2 3
3 2 1
4 2
1 9 1 1
6 1 1 1
2 4
1 5
1 1
Output
YES
NO
YES 题意:开始理解错了,debug到崩溃,半夜才懂得题意是给两个序列A、B,若将A、B中某一序列排序后与另一序列每个对应元素相等,就输出YES(其实意思就是俩序列完全相等咯),或者是如果B序列里面有一个数
与A中对应不相等,那如果给A中对应元素加上范围[-k,k]范围内的某个数可以令A[i]=B[i],且只能改一次,那也输出YES,否则NO;
#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <map>
const int maxen=;
using namespace std;
typedef long long ll;
ll a[maxen],b[maxen];
map<ll,int>mp;
int main(void){
int T,n,k;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&k);
mp.clear();
for(int i=;i<n;++i){
scanf("%lld",&a[i]);
mp[a[i]]++;
}
int pos,count=,flag=;
for(int i=;i<n;++i){
scanf("%lld",&b[i]);
}
for(int i=;i<n;++i){
if(mp[b[i]]){
--mp[b[i]];
if(mp[b[i]]==){
mp.erase(b[i]);
}
}
}
int t=mp.size();
if(t==){
printf("YES\n");
}
else if(t==){
map<ll,int>::iterator start=mp.begin();
ll pos1=start->first; \\指向ll的,即键值;
start++; \\指向下一个
ll pos2=start->first;
if(abs(pos1-pos2)<=k){
printf("YES\n");
}
else{
printf("NO\n");
}
}
else{
printf("NO\n");
}
}
return ;
}

里面有一点小笔记,map的一些函数也灵活用在里面,map真是伟大啊!

看网上都没有这道题的题解,可能是因为太简单了吧,但是菜鸡也从里面学了一些东西,加油!O(∩_∩)O

一只呆在图书馆的猴猴

2019.3.12

C++中map的介绍用法以及Gym题目:Two Sequences的更多相关文章

  1. ES6中map和set用法

    ES6中map和set用法 --转载自廖雪峰的官方网站 一.map Map是一组键值对的结构,具有极快的查找速度. 举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Arra ...

  2. [转] C++ STL中map.erase(it++)用法原理解析

    总结一下map::erase的正确用法. 首先看一下在循环中使用vector::erase时我习惯的用法: for(vector<int>::iterator it = vecInt.be ...

  3. python中map()函数的用法讲解

    map函数的原型是map(function, iterable, -),它的返回结果是一个列表. 参数function传的是一个函数名,可以是python内置的,也可以是自定义的. 参数iterabl ...

  4. python中map函数的用法

    map函数类似一个生成器 具体用例如下: def add(x): a =[,,] b = map(add,[,,]) print( list(map(add,[,,])) ) print(b,type ...

  5. python中map()和dict()的用法

    map()用法 map()是python的内置函数,会根据提供的函数对指定序列做映射. 语法: map(func, iter, ...) 其中func为一个功能函数,iter表示可迭代参数序列.map ...

  6. [转]Java中Map的用法详解

    转载地址:http://www.zhixing123.cn/jsp/30113.html Map简介 将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值.此接口取代 Dictio ...

  7. Java中Map的用法

    Map的一般用法 1.声明一个Map : Map map = new HashMap(); 2 .向map中放值 ,注意: map是key-value的形式存放的,如: map.put("s ...

  8. Java中Map的用法详解

    Map简介 将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值.此接口取代 Dictionary 类,后者完全是一个抽象类,而不是一个接口. Map 接口提供三种collecti ...

  9. STL中map用法

    Map是 STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于 这个特性,它完成有可能在我们处理一对一数据的 ...

随机推荐

  1. ansible笔记(12):变量(一)

    1.定义变量规范 先说说怎样定义变量,变量名应该由字母.数字.下划线组成,变量名需要以字母开头,ansible内置的关键字不能作为变量名. 2.定义变量,使用关键字:vars 定义变量用vars,调用 ...

  2. cadence动态铜皮的参数设置

    注意这幅图和上一幅图那个焊盘距离shape的间距,变大了,这个设置很用的.

  3. java-判断年份是不是闰年

    if ((year%4==0)&&(year%100!=0)||(year%400==0)) {//是闰年 leapYear = true; }

  4. HTMLinput标签

    <input> 标签用于搜集用户信息. 常用的属性: type指定输入项的类型 name定义 input 元素的名称. id给输入项取一个名字,方便后期找到和操作 type指定输入项的类型 ...

  5. Java之字符串替换replace()

    replace(char oldChar, char newChar)返回一个新的字符串,它是通过用 newChar 替换此字符串中出现的所有 oldChar 而生成的 import java.uti ...

  6. 题解【POJ1160】Post Office

    [POJ1160]Post Office Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 22362 Accepted: 1208 ...

  7. eli和字符串 (牛客假期训练)

    链接:https://ac.nowcoder.com/acm/contest/3002/G来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言5242 ...

  8. Django_模型继承

    解决办法

  9. 关于使用ssm与spring时,配置tomcat 虚拟目录( doBase )中的一些坑

    一.使用SSM需要 配置虚拟目录时 tomcat的配置 在tomcat server.xml的<HOST></HOST>中加入以下内容 在配置完成之后,当我们访问URL  为  ...

  10. Linux上后台运行node和springboot服务

    环境:Ubuntu18.04 阿里云云服务器 尝试全局安装forever和pm2均失败,最后以linux自带的nohub启动,以前同样用nohub启动springboot 命令: nohup npm ...