C++中的STL模板库的功能可谓相当强大。今天我们来简单说一下set和map的使用方法。

1.pair

我们先来说一下pair。pair定义在头文件<utility>中,其本身相当于一个已经重定义过的,有两个元素的结构体。它始终以前一个元素(first)为第一关键字,后一个元素(second)为第二关键字。在set或是其他STL容器中使用的时候自动进行按此排序。

pair的定义很简单,定义如下:

pair <int,int> q;

当然里面的数据类型可以改变,后面的变量名也可以任意改变。

或者你可以使用make_pair来新建一个pair,比如:

make_pair(s,t);

在新建pair的时候可以直接赋值,有两种方法,第一种如下:

pair <int,string> p1(,"Hello");

就是在定义的pair的名称后面打上括号,里面直接把值传进去。

第二种如下:

pair <int,string> p2 = make_pair(,"World");

这样的话就是使用一次makepair来对pair赋初值了。

看起来很简单。这样我们就可以在STL中使用pair这种数据结构类型,以进行各种复杂的操作……而在向里面压入pair元素的时候,只要加一个make_pair就可以了。

2.map

map本身是键值(key)和映射值(value)的一个映射。其中key和value可以选择任意数据类型。

(1)创建一个map

这里使用最简单的一种方法,就是直接定义一个map,在里面写上key和value的类型,再定义map的名字。

map <int,int> mp;

(2)向map中添加元素

第一种是直接使用map的下标进行添加,就像使用数组一样。比如:

for(int i = ;i <= n;i++) mp[i] = i * ;

第二种是使用insert函数,将一个pair元素进行插入。比如:

for(int i = ;i <= ;i++) mp.insert(make_pair(i,i*));

以及还有许多神奇的添加方式,在这里不一一讲述了……

(3)在map中查找元素

如果要直接查找元素在map中出现过多少次,那么可以使用count函数,比如:

    map <int,int> mp;
rep(i,,) mp.insert(make_pair(i,i*));
if(mp.count()) printf("Yes\n");

注意这里的count是直接查找键值(key)。

而且因为map中会自动对相同键值去重……所以count相当于只会告诉你这个元素是否有出现过。如果想使用count计算元素出现次数可以使用multimap。

map还有find()函数,可以返回指向所查找元素的迭代器,如果没有此元素就返回指向map尾部的迭代器。

比如:

map <int,int> :: iterator itf;
itf = mp.find();
if(itf != mp.end()) itf->second = ;

注意因为itf是一个迭代器(实际上是指针),所以我们使用了->,如果不愿意使用的话,也可以写成:

(*itf).second

最暴力的方式就是直接在map中用迭代器遍历,比如这样:

map <int,int> :: iterator it;
for(it = mp.begin();it != mp.end();it++) printf("%d->%d\n",it->first,it->second);

因为在map中元素的地址是相连的,所以直接it++即可。如果不愿意用->就使用上面的写法。

还有非常强劲的查找方式,那就是直接使用lowerbound和upperbound。这里要提一下map里面的排序,他是自动按key值从小到大排序,也就是说不可以对map使用sort。

lowerbound和upperbound与平时在数组上的用法都是一样的,一般来说支持key值查找(value作为第二关键字可不可行我还不知道……)一般来讲,我们映射都是一一映射,所以key值应该都是唯一的,直接在key值上查找就可以了。

特别的,如果lower/upperbound找不到元素的话,返回指向容器末尾的迭代器。

(返回的类型如果你开了代码补全可以看到……不过很影响码速)

(4)map中删除元素

删除元素一般来说有三种操作。第一种是直接使用erase函数往里面传实际值,比如:

mp.erase();

第二种就是向里面传一个迭代器,比如:

mp.erase(mp.begin());//显然begin函数返回的是一个迭代器!!

第三种就是传两个迭代器,注意这样删除的是一个左闭右开的区间,比如:

    map <int,int> mp;
rep(i,,) mp.insert(make_pair(i,i));
map <int,int> :: iterator itf;
itf = mp.upper_bound();
mp.erase(mp.begin(),itf);

这样删完之后,你会发现元素还剩15~19,(15没有被删去),用upperbound的话就是16~19了。

这些操作已经基本够用了……还有一个很厉害的swap。这里的swap函数直接交换的是两个map容器,而不是元素。

(下面代码是偷来的)

#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> ( , ) );
m1.insert ( pair <int, int> ( , ) );
m1.insert ( pair <int, int> ( , ) );
m2.insert ( pair <int, int> ( , ) );
m2.insert ( pair <int, int> ( , ) );
m3.insert ( pair <int, int> ( , ) ); 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; system("pause");
}

就是这样啦!

3.set

set即集合,内部是使用红黑树实现的(这么强劲的数据结构蒟蒻学不会QAQ)。不过set的操作还是非常值得学一学的。

(1)创建一个set。

set <int> q;

这是最简单的写法,里面的变量类型是任意的,比如什么pair啦或者是自己定义的结构体。

注意set在你没有进行重载运算符之前,默认是一个小根堆,而且会自动去重。

(2)向set里面插入元素

插入元素好像有好多好多奇妙的方法……不过我还是说最简单的吧,就是直接使用insert函数(set可不再支持用下标插入函数了)比如:

q.insert();//这是int版本的
q.insert((node){a,b,c})//如果你自定义一个结构体,就可以这么传(和平时往队列里面压一样)

(3)在set中查找元素

这里面好多函数在map中都介绍过了,而且在set中的用法和在map中基本一样,比如count,find等等。

不过,我们可以对结构体进行运算符重载,之后就可以愉悦的使用lowerbound对你想要的东西进行查找。

支持多关键字,多种排序方式,我们举个例子。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<set>
#include<vector>
#include<utility>
#include<map>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n') struct node
{
int sum,val;
bool operator < (const node &g)const
{
if(sum == g.sum) return val > g.val;
return sum < g.sum;
}
}
set <node> q;
int main()
{
for(int i = ;i <= n;i++) q.insert((node){a,b,c});
set <node> :: iterator it;
it = q.lower_bound((node){,,});
//这样就可以查找了
return ;
}

非常强力的查找方式。然后……注意重载运算符只能重载小于号。

注意lowerbound返回第一个大于等于查找键值的元素,而upperbound返回的是最后一个大于等于查找键值的元素。

(4)在set中删除元素

这些函数的用法和map基本是一样的,不加以赘述。

具体的操作也就是这些了……set同样是需要用迭代器来加以访问。

希望能帮助到大家。

C++ set和map的简单使用的更多相关文章

  1. Java内存缓存-通过Map定制简单缓存

    缓存 在程序中,缓存是一个高速数据存储层,其中存储了数据子集,且通常是短暂性存储,这样日后再次请求此数据时,速度要比访问数据的主存储位置快.通过缓存,可以高效地重用之前检索或计算的数据. 为什么要用缓 ...

  2. set和map的简单用法

    .set(集合)map(映射)都属于关联类容器 都支持查询一个元素是否存在并能够有效地获取元素. set集合的元素总是从小到大排列,set集合通过二分查找树实现.它具备以下两个特点: ①:独一无二的元 ...

  3. Map的简单语法

    package jaxpsax; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; i ...

  4. HDU1004 Let the Balloon Rise(map的简单用法)

    Let the Balloon Rise Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...

  5. GO的MAP字典简单用法示例

    package main import "fmt" type PersonInfo struct { ID string Name string Address string } ...

  6. scala map操作 简单总结

    在函数式编程中有一个核心的概念之一是转换,所以大部份支持函数式编程语言,都支持一种叫map()的动作,这个动作是可以帮你把某个容器的内容,套上一些动作之后,变成另一个新的容器. 现在我们考虑如何用Op ...

  7. leetcode 249 250 set和map的简单用法

    leetcode249,利用了STL中的set class Solution { public: vector<int> intersection(vector<int>&am ...

  8. js中的Map对象的简单示例

    es6提供一个对象Map, 其功能类似于java中的Map, 下面是java中的Map和js中的Map的简单对比: js中的Map.set()相当于java中的Map.put(), js中的Map.s ...

  9. C++ map的基本操作和使用

    原文地址:http://blog.sina.com.cn/s/blog_61533c9b0100fa7w.html Map是c++的一个标准容器,她提供了很好一对一的关系,在一些程序中建立一个map可 ...

随机推荐

  1. GRYZY #8. 公交车

    公交车(bus) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK在玩一个游戏. 有k群小怪兽想乘坐公交车.第i群小怪兽想从xi出发乘坐公交车到yi.但公交车 ...

  2. Java开发笔记(一百零一)通过加解锁避免资源冲突

    前面介绍了如何通过线程同步来避免多线程并发的资源冲突问题,然而添加synchronized的方式只在简单场合够用,在一些高级场合就暴露出它的局限性,包括但不限于下列几点:1.synchronized必 ...

  3. Xcode not building app with changes incorporated

    Did you clean the build folder by pressing command while the cursor is on the clean option? Are you ...

  4. 实时获取键盘高度 CGSize keyboardSize = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;

    注意:要想实时获取键盘的高度,比如当前如果是中文那么就会增高的.那么需要使用  UIKeyboardFrameEndUserInfoKey 而不是 UIKeyboardFrameBeginUserIn ...

  5. JS---数组(Array)处理函数整理

    1.concat() 连接两个或更多的数组该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本.例如: 代码如下: <script type="text/javascript&q ...

  6. python把日期转换为秒数;日期转为字符串;datetime、date

    1.秒数是相对于1970.1.1号的秒数 2.日期的模块有time.datetime 3. import datetime t = datetime.datetime(2009, 10, 21, 0, ...

  7. 单词number 和 numeral 的区别

    原文: http://blog.sina.com.cn/s/blog_72cd06360100vn7t.html be of 的用法,相当于表征特征或属性的形容词. 简单地说,“of + 名词”等于“ ...

  8. Intel Edision —— 从SSH无法连接到systemd

    前言 原创文章,转载引用务必注明链接.如有疏漏,欢迎斧正. 最近在试用Wyliodrin,安装过程中出现了两个问题,一是无法使用SSH登录到Edison:二是EDISON磁盘的问题.分别涉及到syst ...

  9. sql之浅谈视图的作用

    [数据库]☆★sql之浅谈视图的作用 在一个项目的实际开发过程中牵涉到复杂业务的时候,我们不可避免的须要使用中间表来进行数据连接,有的同学就说了,我能够採用Hibernate进行主外键进行关联啊?多对 ...

  10. c程序设计语言第一章4

    (昨天网络出现了问题,导致这篇没来得及上传,再次补上,今晚照常上传笔记) 练习1.19编写函数r e v e r s e ( s )将字符串s中的字符顺序颠倒过来.使用该函数编写一个程序,每次颠倒一个 ...