高德地图恐怕是最难用的开放平台了吧

最近需求需要接入地图SDK,本想腾讯地图确实不给力,想看看竞品做的如何,发现高德的SDK更烂。

首先是sdk还停留在十年前,使用jar包方式集成。需要拷贝一大坨jar包到工程项目中。

后来下载了demo,一堆报错,2024年了,demo中的gradle版本还是4.6版本,gradle tool 版本更是3.0,与java11 都不兼容。

解决完工程结构后,发现运行竟然报错。报错的原因是变更了jar包中类的处理。

大量的类在构造的时候需要Catch住?真的是毁了三观。

作为一个知名的地图开放平台,显得太不专业了。

一些思考

继续阅读“高德地图恐怕是最难用的开放平台了吧”

求职者,招聘者

年前把工作定下来,虽然有些小插曲,但是看淡就好。 但也收获了不少,主要是结合自己之前面试别人,这次从求职者的角度重新审视了整个过程,发现之前存在的一些问题。

招聘者

见过一系列招聘者,有各种类型的,有外包公司,小型创业公司,中型公司,大型公司,都有接触过,各有各的pros and cons
继续阅读“求职者,招聘者”

对现有云盘的一些想法

事情是这样的,我这个笔记本的ssd硬盘只有256G,虽然目前还够用,但难保我这种不善于整理文件的人来说,迟早会全部占满的, 于是我想通过网盘分担一部分的存储,于是想到了云盘,后来发现好像只有百度有mac版本的同步盘,下载安装后,在本地选择了一个目录作为同步目录,结果,它居然把网盘上所有的文件都同步下来了。这可不是我想要的。

我觉得云盘同步盘应该是像tortoise那样作为一个插件,可以直接对目录同步,微云的那个作为一个单独软件(mac版本)让用户上传下载,真心还是一个上个时代的产品,除了传大文件方便点,对于操作目录还是不够方便, 目前很多云盘提供的网络存储都是好几T的空间了,虽然自己个人资料加起来都没有几个T,个人电脑的硬盘也能够达到T级别,可是对于本地存储空间不大的ssd的笔记本,和移动设备还是需要更多的存储空间, 云盘服务提供的同步盘能够让用户感觉自己的资料放在本地,目前看的百度云盘的同步盘功能是在服务端和本地同时存了一份,如果换一台电脑,比如我到台式机上去,安装同步盘,用同一个帐号登陆,同样会把所有的文件同步下来,可是如果有好几个T的资料呢?我并不需要把所有的文件都同步下来,比如有很多视频资料可以在线播放,何必都要下载下来占本地的资源呢?我希望只在本地留一个镜像文件,如果要同步可以自己手动同步,也可以设置哪些文件或者目录一旦变更就自动同步,这一点对自己写的文档或者代码,可以在切换不同的电脑时感觉会很方便。

程序员浪费生命的几种方式

     程序员应该要爱惜生命,做有用有意义的事情。做有用的事情,有两种方式,一、做一个对用户真正有价值的项目,这个项目是真正有意义有用的;二、朝正确的方向以正确的方式做项目。但是程序员会遇到很多失败的项目,这些系统要么是没有人用没有真正价值,要么是以不正确的方式做项目,使用不当的技术,例如,用报表工具代替查询、用ESB企业总线当作海量数据传输用,或者做一些没有实际用途的功能,如做一个万能的用户自定义查询系统、做用户自定义工作流工具、做用户自定义报表工具,这些项目无疑在浪费程序员的生命。笔者试图总结程序员浪费生命的几种方式,如下。


1、开发一个质量和性能很差的系统

    程序员经常会碰到这样的项目,做出来的系统质量很差,操作无反馈,失败无提示,而且速度很慢,操作时不时要等一会儿。然而,关键是程序员没有机会或者不想参与实施和维护,失去了学习和诊断问题的机会。

2、花费大量人力财力开发一个一次性的项目

这是从事应用开发程序员经常碰到的情况,为某个客户定制化开发一个一次性的项目,然而这个项目要花费巨大的人力成本,最终开发维护周期很长,以巨大亏本收尾或无法收尾。

3、开发一个很漂亮花哨的无人用的系统

    这也是当前常见的情况,客户要做一个亮点政绩工程,要做一个界面漂亮花哨“很炫”的系统,各种图表,各种交互方式、各种监控分析全部堆上,但最终这样的系统是没有人用的。这只是给领导或客人参观用的。

4、全新开发一个原有遗留的系统

     程序员的领导要基于原有的系统重新做一个产品,大幅提升可维护性可扩展性,增加系统的稳定性,减少系统故障。领导决定召集人马,重新进行需求调研,需求分析,架构设计、编码开发测试。但是,这样的事情一再重复,同样类似的需求给不同的客户做了一套又一套新的系统,而且每个系统过一段时间后故障不稳定的情况依旧。各种版本、各种代码库留给了程序员……程序员需要持续给不同客户维护不同版本的系统。

5、开发一个项目范围不确定的系统

    程序员所在的项目,没有人管理项目范围,没有WBS,用户提一点做一点,项目完全没有合同或契约约束,用户要做的越来越多,系统做得越来越大,最终无法控制,客户不满意,程序员也累得半死,试图讨好客户争取更大项目的计划失败。

6、开发一个没有系统角色或涉众的系统

    程序员做的这个项目,虽然都有需求、有功能、有界面,但是奇怪的是,需求没有提到,也没有人知道这些功能是什么人用的。需求没有定义出系统的角色,以及角色所要参与的业务活动。然而这样的项目也不少见,

7、开发一个使用环境不确定的项目

    程序员做的企业应用项目,不知道是给电脑用的还是给移动设备用的,不知道是给IE用的还是其他浏览器用的,不知道是给IE6用的还是IE10用的,不能确定浏览器平台版本。移动设备不知道是iOS还是Android,Android不知道是2.3的还是4.0的,也不能确定手机或平板电脑型号。我们知道,中等规模的企业应用都会比互联网应用要复杂很多,几乎不可能覆盖所有用户的使用终端平台,要做一个优秀系统必须有约束条件,有使用的目标平台。

    针对以上各种情况,程序员经常是没办法干预的,因为,要么这是客户明知故犯的行为,要么是公司部门的战略行为,要么是由于项目经理基本的技能职责缺乏。当然程序员可以假设自己是项目经理,考虑该如何做好这些项目并适时适当的提出问题或解决办法,以免浪费自己的生命。
转载自

IT瘾

Eclipse设置配色方案

以前在网上看到很多程序猿华丽的编辑界面,很是羡慕,问他们那是什么编辑器时,它们简单回一句eclipse,为什么我的确没有这种界面呢??难道要我自己去慢慢调整?后来在网上找到了一个插件。这个是可以自己定义的。

第一步

     安装MPC(Eclipse Marketplace Client)

Eclipse Marketplace是个插件应用商店,很实用的一个功能。

打开 eclipse,help–Eclipse Marketplace Client就能找到 如果没有的话你就要先安装啦!

help–install new software–add

添加name: Eclipse Marketplace Client  (随意起名)

Location:http://download.eclipse.org/mpc/indigo/

添加完成后,work with 选择Eclipse Marketplace Client

第二步 搜索主题

打开MarketPlace Client

 

 

输入Color Theme 查找主题;

 

OK安装插件完成

第三步 设置主题颜色

重启eclipse后再点击window -〉Preferences —> Appearance —> Color Theme

选个自己喜欢的颜色主题吧。。

ainol fire 入手小评

我承认,我是个数码控,但也只能算个小菜。2月份在imp3论坛上逛时,正巧有网友发现mediapad在亚马逊上直降600。于是hold不住买了一台,但用了2个多月就转手了,给我的唯一感觉就是除了分辨率高点外 没有其他什么特点 ,特别是放高清电影居然有点小卡顿,最近又逛论坛时看到了3款机子都有mediapad的分辨率,价格只要都是799。但就外观来说我比较喜欢烈焰,其次还是它使用的是ips屏幕,原本是想买pipo的,看论坛里吹得那么火。 但是由于耗子的种种个人实在不大喜欢(机子还没出来就以用比人的缺点来比自己的优点)。

为什么不选择昂达呢,主要是没有蓝牙又没货,比如从手机发送文件到平板上会比较麻烦。蓝牙还可以用来听音乐什么的,比较方便。艾诺电池也是一大亮点,当初mediapad我感觉电池不是很耐用。

与此同时,刚好有人发帖说烈焰接受预定了大概5天左右到货。我看配置还行,样子也不错,就预定了一台,在兆联定的。应该是第一批吧,有人说我们是小白鼠,其实想想也觉得有点冲动了。。但我以前高中时买过艾诺的mp4 是 v2000se。当时为数不多的支持所有格式 特别是rmvb 和flv格式的mp4啊 。被我摔过不知道多少次了。一直都没坏(因为是铁壳子的)。也因为艾诺我才知道了imp3 当时它官网很多评测和固件在imp3论坛发布的。

好像有点扯远了。。。。。。

切入正题吧: 机子是我8月13拍的。兆联8月17发的货 今天中午到货,,不 应该是厂家 ,机子是直接从深圳发过来的 ,其余赠品兆联过几天再补发 。

拆开盒子,包装实在是有点寒酸,特别是那块气泡膜。右上角那个是充电器。

充电器 5V 2ma

来看看那层气泡膜吧 ,还是用手撕开的,没有撕齐 好吧 这应该是快递干的。。

终于见到可爱的包装盒啦。

有点像mediapad的包装盒 但薄大概一半。

有木有觉得那个塑料保护套是随手捡来的一个保鲜袋???

好吧拆开它…..屏幕很干净应该是没人拆过,但是 请注意 它没贴膜。手指很容易留下痕迹。莫非是防刮的大猩猩??

 

摄像头位置让我比较无语。中间不是 ,侧边也不是,给人感觉好像是准备放在中间,但一时手误放偏了。

机身还是比较薄的 。感觉和mediapad差不多。烈焰感觉要轻一些,估计采用的原料不同。mediapad背壳重一些吧、

 

ainol的标签。

机身图片

看看盒子里还有什么吧 右边是说明书 合格证 保修卡 左边是 数据线和耳机 如下图

这是随机的配件

内置QQ HD 正在烈焰群里聊天呢,

和同学台电P85双核对比  显得小巧 屏幕细粒得多

图片到此为止。

——————————–华丽分割线———————————————–

我讲一下我的一些操作体验:

1  我的是完美屏。没有亮点 没有漏光。。这一点我很满意。我上次买的mediapad有2个亮点 下边有漏光。这台没有。

2  电量还是令人满意的,我一直不间断玩了一下午。大概能坚持5个小时左右吧。

这是电量使用截图

这里我有点疑问  不知道是我设置了动态壁纸的原因还是电池本身的原因 在电量到50左右的时候会掉的非常快。大家从图中可以看到。顺便问一下其他人有这个情况吗?

机子的特色 优点我就不多说了 参数大家都知道,

我的机子跑分7678

本机缺点  不知道是否个例

1  发热比较严重,特别是左下角HDMI部分 ,玩游戏或者用安兔兔跑分 预测温度40-50度  这种天气(苦逼学生没得空调吹 )握在手上有点出汗。不知道冬天会不会成为我的优乐美呢。。

2  系统有点小问题。 比如明明是自动光感应 ,点击设置的时候,会变成手动的了。。(尽管没有滑动屏幕亮度的滑动条), 关闭重力感应 在屏幕锁定时 失效。

3 wifi 信号没同学的P85好 。(大家就不要认为P85就好些 他机子一天死几次机 就是待机的时候按电源无法启动,只能扣电池)。

4 做工我也想吐槽 我机子按右上角时会有咯吱咯吱的响声。

 

暂时就发现这些问题,我想发现问题才是好的,这样才能做到尽善尽美。

 

在HTML嵌入SWF的最佳方法

前一阵弄个flash到网页中,ie下总是要刷新几下才出来,找了个完美的。。。在此分享下

<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
<html xmlns=”http://www.w3.org/1999/xhtml” lang=”en” xml:lang=”en”>
<head>
<title>SWFObject – step 1</title>
<meta http-equiv=”Content-Type” content=”text/html; charset=iso-8859-1″ />
</head>
<body>
<div>

<object classid=”clsid:D27CDB6E-AE6D-11cf-96B8-444553540000″ width=”780″ height=”420″>
<param name=”movie” value=”myContent.swf” />
<!–[if !IE]>–>
<object type=”application/x-shockwave-flash” data=”myContent.swf” width=”780″ height=”420″>
<!–<![endif]–>
<p>Alternative content</p>
<!–[if !IE]>–>
</object>
<!–<![endif]–>
</object>

</div>
</body>
</html>

c++ map的使用方法

—————-来自烙印空间———————

Map是c++的一个标准容器,它提供了很好一对一的关系,在一些程序中建立一个map可以起到事半功倍的效果,总结了一些map基本简单实用的操作! 1. map构造函数; map<string , int >mapstring; map<int ,string >mapint; map<sring, char>mapstring; map< char ,string>mapchar; map<char ,int>mapchar; map<int ,char >mapint;

2. map添加数据; map<int ,string> maplive; 1.maplive.insert(pair<int,string>(102,”aclive”)); 2.maplive.insert(map<int,string>::value_type(321,”hai”)); 3, maplive[112]=”April”;//map中最简单最常用的插入添加! 3,map中元素的查找:

find()函数返回一个迭代器指向键值为key的元素,如果没找到就返回指向map尾部的迭代器。

map<int ,string >::iterator l_it;; l_it=maplive.find(112); if(l_it==maplive.end()) cout<<“we do not find 112″<<endl; else cout<<“wo find 112″<<endl; 4,map中元素的删除: 如果删除112; map<int ,string >::iterator l_it;; l_it=maplive.find(112); if(l_it==maplive.end()) cout<<“we do not find 112″<<endl; else maplive.erase(l_it); //delete 112; 5,map中 swap的用法: Map中的swap不是一个容器中的元素交换,而是两个容器交换; For example: #include <map> #include <iostream>

using namespace std;

int main( ) { map <int, int> m1, m2, m3; map <int, int>::iterator m1_Iter;

m1.insert ( pair <int, int> ( 1, 10 ) ); m1.insert ( pair <int, int> ( 2, 20 ) ); m1.insert ( pair <int, int> ( 3, 30 ) ); m2.insert ( pair <int, int> ( 10, 100 ) ); m2.insert ( pair <int, int> ( 20, 200 ) ); m3.insert ( pair <int, int> ( 30, 300 ) );

cout << “The original map m1 is:”; for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ ) cout << ” ” << m1_Iter->second; cout << “.” << endl;

// This is the member function version of swap //m2 is said to be the argument map; m1 the target map m1.swap( m2 );

cout << “After swapping with m2, map m1 is:”; for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ ) cout << ” ” << m1_Iter -> second; cout << “.” << endl; cout << “After swapping with m2, map m2 is:”; for ( m1_Iter = m2.begin( ); m1_Iter != m2.end( ); m1_Iter++ ) cout << ” ” << m1_Iter -> second; cout << “.” << endl; // This is the specialized template version of swap swap( m1, m3 );

cout << “After swapping with m3, map m1 is:”; for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ ) cout << ” ” << m1_Iter -> second; cout << “.” << endl; }

6.map的sort问题: Map中的元素是自动按key升序排序,所以不能对map用sort函数: For example: #include <map> #include <iostream>

using namespace std;

int main( ) { map <int, int> m1; map <int, int>::iterator m1_Iter;

m1.insert ( pair <int, int> ( 1, 20 ) ); m1.insert ( pair <int, int> ( 4, 40 ) ); m1.insert ( pair <int, int> ( 3, 60 ) ); m1.insert ( pair <int, int> ( 2, 50 ) ); m1.insert ( pair <int, int> ( 6, 40 ) ); m1.insert ( pair <int, int> ( 7, 30 ) );

cout << “The original map m1 is:”<<endl; for ( m1_Iter = m1.begin( ); m1_Iter != m1.end( ); m1_Iter++ ) cout << m1_Iter->first<<” “<<m1_Iter->second<<endl; } The original map m1 is: 1 20 2 50 3 60 4 40 6 40 7 30 请按任意键继续. . .

7, map的基本操作函数: C++ Maps是一种关联式容器,包含“关键字/值”对 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 upper_bound() 返回键值>给定元素的第一个位置 value_comp() 返回比较元素value的函数

———————-来自酷勤网—————————

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

下面举例说明什么是一对一的数据映射。比如一个班级中,每个学生的学号跟他的姓名就存在着一一映射的关系,这个模型用map可能轻易描述,很明显学号用int描述,姓名用字符串描述(本篇文章中不用char *来描述字符串,而是采用STL中string来描述),下面给出map描述代码:

Map<int, string> mapStudent;

1.       map的构造函数

map共提供了6个构造函数,这块涉及到内存分配器这些东西,略过不表,在下面我们将接触到一些map的构造方法,这里要说下的就是,我们通常用如下方法构造一个map:

Map<int, string> mapStudent;

2.       数据的插入

在构造map容器后,我们就可以往里面插入数据了。这里讲三种插入数据的方法:

第一种:用insert函数插入pair数据,下面举例说明(以下代码虽然是随手写的,应该可以在VC和GCC下编译通过,大家可以运行下看什么效果,在VC下请加入这条语句,屏蔽4786警告  #pragma warning (disable:4786) )

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(pair<int, string>(1, “student_one”));

mapStudent.insert(pair<int, string>(2, “student_two”));

mapStudent.insert(pair<int, string>(3, “student_three”));

map<int, string>::iterator  iter;

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

{

Cout<<iter->first<<”   ”<<iter->second<<end;

}

}

第二种:用insert函数插入value_type数据,下面举例说明

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(map<int, string>::value_type (1, “student_one”));

mapStudent.insert(map<int, string>::value_type (2, “student_two”));

mapStudent.insert(map<int, string>::value_type (3, “student_three”));

map<int, string>::iterator  iter;

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

{

Cout<<iter->first<<”   ”<<iter->second<<end;

}

}

第三种:用数组方式插入数据,下面举例说明

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent[1] =  “student_one”;

mapStudent[2] =  “student_two”;

mapStudent[3] =  “student_three”;

map<int, string>::iterator  iter;

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

{

Cout<<iter->first<<”   ”<<iter->second<<end;

}

}

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

mapStudent.insert(map<int, string>::value_type (1, “student_one”));

mapStudent.insert(map<int, string>::value_type (1, “student_two”));

上面这两条语句执行后,map中1这个关键字对应的值是“student_one”,第二条语句并没有生效,那么这就涉及到我们怎么知道insert语句是否插入成功的问题了,可以用pair来获得是否插入成功,程序如下

Pair<map<int, string>::iterator, bool> Insert_Pair;

Insert_Pair = mapStudent.insert(map<int, string>::value_type (1, “student_one”));

我们通过pair的第二个变量来知道是否插入成功,它的第一个变量返回的是一个map的迭代器,如果插入成功的话Insert_Pair.second应该是true的,否则为false。

下面给出完成代码,演示插入成功与否问题

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

Pair<map<int, string>::iterator, bool> Insert_Pair;

Insert_Pair = mapStudent.insert(pair<int, string>(1, “student_one”));

If(Insert_Pair.second == true)

{

Cout<<”Insert Successfully”<<endl;

}

Else

{

Cout<<”Insert Failure”<<endl;

}

Insert_Pair = mapStudent.insert(pair<int, string>(1, “student_two”));

If(Insert_Pair.second == true)

{

Cout<<”Insert Successfully”<<endl;

}

Else

{

Cout<<”Insert Failure”<<endl;

}

map<int, string>::iterator  iter;

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

{

Cout<<iter->first<<”   ”<<iter->second<<end;

}

}

大家可以用如下程序,看下用数组插入在数据覆盖上的效果

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent[1] =  “student_one”;

mapStudent[1] =  “student_two”;

mapStudent[2] =  “student_three”;

map<int, string>::iterator  iter;

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

{

Cout<<iter->first<<”   ”<<iter->second<<end;

}

}

3.       map的大小

在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:

Int nSize = mapStudent.size();

4.       数据的遍历

这里也提供三种方法,对map进行遍历

第一种:应用前向迭代器,上面举例程序中到处都是了,略过不表

第二种:应用反相迭代器,下面举例说明,要体会效果,请自个动手运行程序

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(pair<int, string>(1, “student_one”));

mapStudent.insert(pair<int, string>(2, “student_two”));

mapStudent.insert(pair<int, string>(3, “student_three”));

map<int, string>::reverse_iterator  iter;

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

{

Cout<<iter->first<<”   ”<<iter->second<<end;

}

}

第三种:用数组方式,程序说明如下

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(pair<int, string>(1, “student_one”));

mapStudent.insert(pair<int, string>(2, “student_two”));

mapStudent.insert(pair<int, string>(3, “student_three”));

int nSize = mapStudent.size()

//此处有误,应该是 for(int nIndex = 1; nIndex <= nSize; nIndex++)

//by rainfish

for(int nIndex = 0; nIndex < nSize; nIndex++)

{

Cout<<mapStudent[nIndex]<<end;

}

}

5.       数据的查找(包括判定这个关键字是否在map中出现)

在这里我们将体会,map在数据插入时保证有序的好处。

要判定一个数据(关键字)是否在map中出现的方法比较多,这里标题虽然是数据的查找,在这里将穿插着大量的map基本用法。

这里给出三种数据查找方法

第一种:用count函数来判定关键字是否出现,其缺点是无法定位数据出现位置,由于map的特性,一对一的映射关系,就决定了count函数的返回值只有两个,要么是0,要么是1,出现的情况,当然是返回1了

第二种:用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器,程序说明

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(pair<int, string>(1, “student_one”));

mapStudent.insert(pair<int, string>(2, “student_two”));

mapStudent.insert(pair<int, string>(3, “student_three”));

map<int, string>::iterator iter;

iter = mapStudent.find(1);

if(iter != mapStudent.end())

{

Cout<<”Find, the value is ”<<iter->second<<endl;

}

Else

{

Cout<<”Do not Find”<<endl;

}

}

第三种:这个方法用来判定数据是否出现,是显得笨了点,但是,我打算在这里讲解

Lower_bound函数用法,这个函数用来返回要查找关键字的下界(是一个迭代器)

Upper_bound函数用法,这个函数用来返回要查找关键字的上界(是一个迭代器)

例如:map中已经插入了1,2,3,4的话,如果lower_bound(2)的话,返回的2,而upper-bound(2)的话,返回的就是3

Equal_range函数返回一个pair,pair里面第一个变量是Lower_bound返回的迭代器,pair里面第二个迭代器是Upper_bound返回的迭代器,如果这两个迭代器相等的话,则说明map中不出现这个关键字,程序说明

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent[1] =  “student_one”;

mapStudent[3] =  “student_three”;

mapStudent[5] =  “student_five”;

map<int, string>::iterator  iter;

iter = mapStudent.lower_bound(2);

{

//返回的是下界3的迭代器

Cout<<iter->second<<endl;

}

iter = mapStudent.lower_bound(3);

{

//返回的是下界3的迭代器

Cout<<iter->second<<endl;

}

 

iter = mapStudent.upper_bound(2);

{

//返回的是上界3的迭代器

Cout<<iter->second<<endl;

}

iter = mapStudent.upper_bound(3);

{

//返回的是上界5的迭代器

Cout<<iter->second<<endl;

}

 

Pair<map<int, string>::iterator, map<int, string>::iterator> mapPair;

mapPair = mapStudent.equal_range(2);

if(mapPair.first == mapPair.second)        {

cout<<”Do not Find”<<endl;

}

Else

{

Cout<<”Find”<<endl; }

mapPair = mapStudent.equal_range(3);

if(mapPair.first == mapPair.second)        {

cout<<”Do not Find”<<endl;

}

Else

{

Cout<<”Find”<<endl; }

}

6.       数据的清空与判空

清空map中的数据可以用clear()函数,判定map中是否有数据可以用empty()函数,它返回true则说明是空map

7.       数据的删除

这里要用到erase函数,它有三个重载了的函数,下面在例子中详细说明它们的用法

#include <map>

#include <string>

#include <iostream>

Using namespace std;

Int main()

{

Map<int, string> mapStudent;

mapStudent.insert(pair<int, string>(1, “student_one”));

mapStudent.insert(pair<int, string>(2, “student_two”));

mapStudent.insert(pair<int, string>(3, “student_three”));

 

//如果你要演示输出效果,请选择以下的一种,你看到的效果会比较好

//如果要删除1,用迭代器删除

map<int, string>::iterator iter;

iter = mapStudent.find(1);

mapStudent.erase(iter);

 

//如果要删除1,用关键字删除

Int n = mapStudent.erase(1);//如果删除了会返回1,否则返回0

 

//用迭代器,成片的删除

//一下代码把整个map清空

mapStudent.earse(mapStudent.begin(), mapStudent.end());

//成片删除要注意的是,也是STL的特性,删除区间是一个前闭后开的集合

 

//自个加上遍历代码,打印输出吧

}

8.       其他一些函数用法

这里有swap,key_comp,value_comp,get_allocator等函数,感觉到这些函数在编程用的不是很多,略过不表,有兴趣的话可以自个研究

9.       排序

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

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

#include <map>

#include <string>

Using namespace std;

Typedef struct tagStudentInfo

{

Int      nID;

String   strName;

}StudentInfo, *PStudentInfo;  //学生信息

 

Int main()

{

int nSize;

//用学生信息映射分数

map<StudentInfo, int>mapStudent;

map<StudentInfo, int>::iterator iter;

StudentInfo studentInfo;

studentInfo.nID = 1;

studentInfo.strName = “student_one”;

mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));

studentInfo.nID = 2;

studentInfo.strName = “student_two”;

mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));

 

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

cout<<iter->first.nID<<endl<<iter->first.strName<<endl<<iter->second<<endl;

 

}

以上程序是无法编译通过的,只要重载小于号,就OK了,如下:

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) < 0;

Return false;

}

}StudentInfo, *PStudentInfo;  //学生信息

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

#include <map>

#include <string>

Using namespace std;

Typedef struct tagStudentInfo

{

Int      nID;

String   strName;

}StudentInfo, *PStudentInfo;  //学生信息

 

Classs 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) < 0;

Return false;

}

};

 

Int main()

{

//用学生信息映射分数

Map<StudentInfo, int, sort>mapStudent;

StudentInfo studentInfo;

studentInfo.nID = 1;

studentInfo.strName = “student_one”;

mapStudent.insert(pair<StudentInfo, int>(studentInfo, 90));

studentInfo.nID = 2;

studentInfo.strName = “student_two”;

mapStudent.insert(pair<StudentInfo, int>(studentInfo, 80));

}

10.   另外

由于STL是一个统一的整体,map的很多用法都和STL中其它的东西结合在一起,比如在排序上,这里默认用的是小于号,即less<>,如果要从大到小排序呢,这里涉及到的东西很多,在此无法一一加以说明。

还要说明的是,map中由于它内部有序,由红黑树保证,因此很多函数执行的时间复杂度都是log2N的,如果用map函数可以实现的功能,而STL  Algorithm也可以完成该功能,建议用map自带函数,效率高一些。

下面说下,map在空间上的特性,否则,估计你用起来会有时候表现的比较郁闷,由于map的每个数据对应红黑树上的一个节点,这个节点在不保存你的数据时,是占用16个字节的,一个父节点指针,左右孩子指针,还有一个枚举值(标示红黑的,相当于平衡二叉树中的平衡因子),我想大家应该知道,这些地方很费内存了吧,不说了……