C++中map的介绍用法以及Gym题目:Two Sequences
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
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
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的更多相关文章
- ES6中map和set用法
ES6中map和set用法 --转载自廖雪峰的官方网站 一.map Map是一组键值对的结构,具有极快的查找速度. 举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Arra ...
- [转] C++ STL中map.erase(it++)用法原理解析
总结一下map::erase的正确用法. 首先看一下在循环中使用vector::erase时我习惯的用法: for(vector<int>::iterator it = vecInt.be ...
- python中map()函数的用法讲解
map函数的原型是map(function, iterable, -),它的返回结果是一个列表. 参数function传的是一个函数名,可以是python内置的,也可以是自定义的. 参数iterabl ...
- python中map函数的用法
map函数类似一个生成器 具体用例如下: def add(x): a =[,,] b = map(add,[,,]) print( list(map(add,[,,])) ) print(b,type ...
- python中map()和dict()的用法
map()用法 map()是python的内置函数,会根据提供的函数对指定序列做映射. 语法: map(func, iter, ...) 其中func为一个功能函数,iter表示可迭代参数序列.map ...
- [转]Java中Map的用法详解
转载地址:http://www.zhixing123.cn/jsp/30113.html Map简介 将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值.此接口取代 Dictio ...
- Java中Map的用法
Map的一般用法 1.声明一个Map : Map map = new HashMap(); 2 .向map中放值 ,注意: map是key-value的形式存放的,如: map.put("s ...
- Java中Map的用法详解
Map简介 将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值.此接口取代 Dictionary 类,后者完全是一个抽象类,而不是一个接口. Map 接口提供三种collecti ...
- STL中map用法
Map是 STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于 这个特性,它完成有可能在我们处理一对一数据的 ...
随机推荐
- 用html5自带表单验证 并且用ajax提交的解决方法(附例子)
用submit来提交表单,然后在js中监听submit方法,用ajax提交表单最后阻止submit的自动提交. 在标准浏览器中,阻止浏览器默认行为使用event.preventDefault(),而在 ...
- MySQL 触发器trigger
一.触发器概念 触发器(trigger):监视某种情况,并触发某种操作. 触发器创建语法四要素:1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(af ...
- AcWing 827. 双链表
https://www.acwing.com/problem/content/829/ #include <iostream> using namespace std; ; int m; ...
- 题解【BZOJ4145】「AMPPZ2014」The Prices
题目描述 你要购买 \(m\) 种物品各一件,一共有 \(n\) 家商店,你到第 \(i\) 家商店的路费为 \(d[i]\),在第 \(i\) 家商店购买第 \(j\) 种物品的费用为 \(c[i] ...
- 用git无法连接github的解决方法
如果要從 GitHub 存取 Git 儲存庫,建議還是多採用 SSH 與 HTTPS 通訊協定最為穩定可靠,因此我的替代方案就是設定 Git 的全域設定值 ( –global ),預設將所有 git: ...
- js的一些基础
事件对象: 就是用来存储事件相关的信息 事件对象存储信息有: 事件的类别,如:click,keydown等等 点击事件的位置 点击的哪一个键 等等 用于阻止事件流,用于阻止浏览器默认动作(表单提交.a ...
- mybatis报错:A query was run and no Result Maps were found for the Mapped Statement、、Property [login_ip] not found on type [com.thinkgem.jeesite.common.permission.entity.PremissUser]问题解决
今天在做ssm项目的时候出现了: 先是出现 了错误: mybatis报错:A query was run and no Result Maps were found for the Mapped St ...
- MomentJS记录下开发中用到的日期
1.计算当前周一到周日的日期 var weekOfday = moment().format('E');//计算今天是这周第几天 var last_monday = moment().s ...
- C++11 新特性学习
在Linux下编译C++11 #include<typeinfo> int main() { auto a=; cout<<typeid(a).name()<<en ...
- tarsgo初探
参考:https://mp.weixin.qq.com/s/aO8ybUiu5htqcoGAwxwc5Q?utm_source=tuicool&utm_medium=referral 1.Go ...