[STL]set/multiset用法详解[自从VS2010开始,set的iterator类型自动就是const的引用类型]
集合
Set、multiset都是集合类,差别在与set中不允许有重复元素,multiset中允许有重复元素。

sets和multiset内部以平衡二叉树实现

1. 常用函数
1) 构造函数和析构函数
set c:创建空集合,不包含任何元素
set c(op):以op为排序准则,产生一个空的set
set c1(c2):复制c2中的元素到c1中
set c(const value_type *first, const value_type* last):复制[first, last)之间元素构成新集合
set c(const value_type *first, const value_type* last,op):以op为排序准则,复制[first, last)之间元素构成新集合。
c.~set()销毁所有元素,释放内存
multiset mc:创建空集合,不包含任何元素
multiset mc(op):以op为排序准则,产生一个空的set
multiset c1(c2):复制c2中的元素到c1中
multiset c(const value_type *first, const value_type* last):复制[first, last)之间元素构成新集合
multiset c(const value_type *first, const value_type* last,op):以op为排序准则,复制[first, last)之间元素构成新集合。
c.~set()销毁所有元素,释放内存
- // constructing sets
- #include <iostream>
- #include <set>
- bool fncomp (int lhs, int rhs) {return lhs<rhs;}
- struct classcomp {
- bool operator() (const int& lhs, const int& rhs) const
- {return lhs<rhs;}
- };
- int main ()
- {
- std::set<int> first; // empty set of ints
- int myints[]= {10,20,30,40,50};
- std::set<int> second (myints,myints+5); // range
- std::set<int> third (second); // a copy of second
- std::set<int> fourth (second.begin(), second.end()); // iterator ctor.
- std::set<int,classcomp> fifth; // class as Compare
- bool(*fn_pt)(int,int) = fncomp;
- std::set<int,bool(*)(int,int)> sixth (fn_pt); // function pointer as Compare
- return 0;
- }
2) 大小、判断空函数
int size() const:返回容器元素个数
bool empty() const:判断容器是否为空,若返回true,表明容器已空
3) 增加、删除函数
pair<iterator,bool> insert( x):插入元素x
iterator insert(iterator it,x):在迭代器it处插入元素x
void insert(const value_type *first,const value_type *last):插入[first, last)之间元素
iterator erase(iterator it):删除迭代器指针it处元素
iterator erase(iterator first,iterator last):删除[first, last)之间元素
size_type erase(const Key& key):删除元素值等于key的元素
- #include <iostream>
- #include <set>
- int main ()
- {
- std::set<int> myset;
- std::set<int>::iterator it;
- std::pair<std::set<int>::iterator,bool> ret;
- // set some initial values:
- for (int i=1; i<=5; ++i) myset.insert(i*10); // set: 10 20 30 40 50
- ret = myset.insert(20); // no new element inserted
- if (ret.second==false) it=ret.first; // "it" now points to element 20
- myset.insert (it,25); // max efficiency inserting
- myset.insert (it,24); // max efficiency inserting
- myset.insert (it,26); // no max efficiency inserting
- int myints[]= {5,10,15}; // 10 already in set, not inserted
- myset.insert (myints,myints+3);
- std::cout << "myset contains:";
- for (it=myset.begin(); it!=myset.end(); ++it)
- std::cout << ' ' << *it;
- std::cout << '\n';
- return 0;
- }
- #include <iostream>
- #include <set>
- int main ()
- {
- std::set<int> myset;
- std::set<int>::iterator it;
- // insert some values:
- for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90
- it = myset.begin();
- ++it; // "it" points now to 20
- myset.erase (it);
- myset.erase (40);
- it = myset.find (60);
- myset.erase (it, myset.end());
- std::cout << "myset contains:";
- for (it=myset.begin(); it!=myset.end(); ++it)
- std::cout << ' ' << *it;
- std::cout << '\n';
- return 0;
- }
4) 遍历函数
iterator begin():返回首元素的迭代器指针
iterator end():返回尾元素的迭代器指针
reverse_iterator rbegin():返回尾元素的逆向迭代器指针
reverse_iterator rend():返回首元素前一个位置的迭代器指针
- #include <iostream>
- #include <set>
- int main ()
- {
- int myints[] = {75,23,65,42,13};
- std::set<int> myset (myints,myints+5);
- std::cout << "myset contains:";
- for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
- std::cout << ' ' << *it;
- std::cout << '\n';
- return 0;
- }
5) 操作函数
const_iterator lower_bound(const Key& key):返回容器中大于等于key的迭代器指针
const_iterator upper_bound(const Key& key):返回容器中大于key的迭代器指针
int count(const Key& key) const:返回容器中元素等于key的元素的个数
pair<const_iterator,const_iterator> equal_range(const Key& key) const:返回容器中元素值等于key的迭代指针[first, last)
const_iterator find(const Key& key) const:查找功能,返回元素值等于key的迭代器指针
void swap(set& s):交换集合元素
void swap(multiset& s):交换多集合元素
- #include <iostream>
- #include <set>
- int main ()
- {
- std::set<int> myset;
- std::set<int>::iterator itlow,itup;
- for (int i=1; i<10; i++) myset.insert(i*10); // 10 20 30 40 50 60 70 80 90
- itlow=myset.lower_bound (30); // ^
- itup=myset.upper_bound (60); // ^
- myset.erase(itlow,itup); // 10 20 70 80 90
- std::cout << "myset contains:";
- for (std::set<int>::iterator it=myset.begin(); it!=myset.end(); ++it)
- std::cout << ' ' << *it;
- std::cout << '\n';
- return 0;
- }
- #include "stdafx.h"
- #include <iostream>
- #include <set>
- using namespace std;
- int main ()
- {
- set<int> myset;
- for (int i=1; i<=5; i++) myset.insert(i*10); // myset: 10 20 30 40 50
- pair<set<int>::const_iterator,set<int>::const_iterator> ret;
- ret = myset.equal_range(30);
- cout << "the lower bound points to: " << *ret.first << '\n';
- cout << "the upper bound points to: " << *ret.second << '\n';
- return 0;
- }
- #include "stdafx.h"
- #include <iostream>
- #include <set>
- using namespace std;
- int main ()
- {
- int myints[]={12,75,10,32,20,25};
- set<int> first (myints,myints+3); // 10,12,75
- set<int> second (myints+3,myints+6); // 20,25,32
- first.swap(second);
- cout << "first contains:";
- for (set<int>::iterator it=first.begin(); it!=first.end(); ++it)
- cout << ' ' << *it;
- cout << '\n';
- cout << "second contains:";
- for (set<int>::iterator it=second.begin(); it!=second.end(); ++it)
- cout << ' ' << *it;
- cout << '\n';
- return 0;
- }
自从VS2010开始,set的iterator类型自动就是const的引用类型,因此当set保存的是类类型时,对iterator解引用无法调用类的非const成员。
解决方法为:
- //item是一个类,bool isEnd()是Item的一个成员
- for (set<Item>::iterator i = ItemSet.begin(); i != ItemSet.end(); i++)
- {
- const Item &item1 = const_cast<Item&>(*i);
- Item &item2 = const_cast<Item&>(item1);
- if (item2.isEnd())
- {//do something}
const_cast:(转自百度百科)用法:const_cast<type_id> (expression)该运算符用来修改类型的const或volatile属性。除了const 或volatile修饰之外, type_id和expression的类型是一样的。一、常量指针被转化成非常量的指针,并且仍然指向原来的对象;二、常量引用被转换成非常量的引用,并且仍然指向原来的对象;为什么要设置为const reference?
The iterator should give you a const reference (and that's what the Standard says it should do), because changing the thing referred to would destroy the validity of the set's underlying data structure - the set doesn't "know" that the field you are changing is not actually part of the key. The alternatives are to make changes by removing and re-adding, or to use a std::map instead.
因为改变引用指向的对象会破坏set隐藏的数据结构的正确性。
[STL]set/multiset用法详解[自从VS2010开始,set的iterator类型自动就是const的引用类型]的更多相关文章
- C++中的STL中map用法详解(转)
原文地址: https://www.cnblogs.com/fnlingnzb-learner/p/5833051.html C++中的STL中map用法详解 Map是STL的一个关联容器,它提供 ...
- STL stack 常见用法详解
<算法笔记>学习笔记 stack 常见用法详解 stack翻译为栈,是STL中实现的一个后进先出的容器.' 1.stack的定义 //要使用stack,应先添加头文件#include &l ...
- STL priority_queue 常见用法详解
<算法笔记>学习笔记 priority_queue 常见用法详解 //priority_queue又称优先队列,其底层时用堆来实现的. //在优先队列中,队首元素一定是当前队列中优先级最高 ...
- STL queue 常见用法详解
<算法笔记>学习笔记 queue 常见用法详解 queue翻译为队列,在STL中主要则是实现了一个先进先出的容器. 1. queue 的定义 //要使用queue,应先添加头文件#incl ...
- STL map 常见用法详解
<算法笔记>学习笔记 map 常见用法详解 map翻译为映射,也是常用的STL容器 map可以将任何基本类型(包括STL容器)映射到任何基本类型(包括STL容器) 1. map 的定义 / ...
- STL set 常见用法详解
<算法笔记>学习笔记 set 常见用法详解 set是一个内部自动有序且不含重复元素的容器 1. set 的定义 //单独定义一个set set<typename> name: ...
- STL vector常见用法详解
<算法笔记>中摘取 vector常见用法详解 1. vector的定义 vector<typename> name; //typename可以是任何基本类型,例如int, do ...
- STL pair 常见用法详解
<算法笔记>学习笔记 pair 常见用法详解 //pair是一个很实用的"小玩意",当想要将两个元素绑在一起作为一个合成元素, //又不想因此定义结构体时,使用pair ...
- STL string 常见用法详解
string 常见用法详解 1. string 的定义 //定义string的方式跟基本数据类型相同,只需要在string后跟上变量名即可 string str; //如果要初始化,可以直接给stri ...
随机推荐
- Perforce 使用笔记
Perforce requires at least two executables: the server (p4d), and at least one Perforce client progr ...
- TOMCAT 关闭报错:Tomcat did not stop in time. PID file was not removed
关闭tomcat的时候,报出如下错误信息: # ./shutdown.sh Using CATALINA_BASE: /opt/openkm-6.3.1-community/tomcat Using ...
- (Command Pattern)命令模式
定义 将“请求”封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 结构图: 命令模式的角色划分: Reciever(命令的接收者):接收命令,并知道如何进行必 ...
- centos 6.4下安装postgresql 9.2
我的linux版本是centos 6.4 ,准备安装postgresql 9.2 根据官方说明: http://www.postgresql.org/download/linux/redhat/ 缺省 ...
- #pragma message的作用
一般情况下,#pragma message( messagestring )是在编译期间,将一个文字串(messagestring)发送到标准输出窗口.典型的使用方法是在编译时报告和显示信息.下面的代 ...
- J2EE sitemesh使用
maven包含sitemesh: <dependency> <groupId>opensymphony</groupId> <artifactId>si ...
- CCF真题之窗口
201403-2 问题描述 在某图形操作系统中,有 N 个窗口,每个窗口都是一个两边与坐标轴分别平行的矩形区域.窗口的边界上的点也属于该窗口.窗口之间有层次的区别,在多于一个窗口重叠的区域里,只会显示 ...
- c# 获取路径的几种方法
1.取得控制台应用程序的根目录方法 方法1.Environment.CurrentDirectory 取得或设置当前工作目录的完整限定路径方法2.AppDomain.CurrentDomain.Bas ...
- C#语言基础2016/3/6
一. 基础知识 输入输出 Console.Write();//输出语句,自动换行 Console.WriteLine();//输出语句 Console.WriteLine();输入语句 Consol ...
- 【兄弟连ThinkPHP】1、介绍和安装
琢磨了好几天的ThinkPHP了,兄弟连的视频真心不错,下面是记得一些要点,只做备忘,有兴趣的朋友请去百度兄弟连. ## ThinkPHP 3 介绍及安装#讲师:赵桐正微博:http://weibo. ...