1.pair的使用
pair相当于是包含有两个变量的struct,同样类型的pair变量可以直接赋值,这里比struct要方便,写的时候也很简单,确实很好用,而且first和second可以用代码补全。
pair使用头文件iostream,记得要声明using namespace std;
例如pair<set<double>::iterator, bool> r是由一个set迭代器和value值组成,r = s.insert(v)把pair的value值=insert的返回值,如果插入成功则返回true。
2.关联容器
(1)set集合,其实set和其它容器相比,就是自动排序,如果自己不定义比较函数,就会采用默认的比较函数,默认从小到大,可以改成从大到小,如下代码:
struct myComp //自定义一个mycomp比较结构体加()重载
{
bool operator()(const int&a,const int&b)
{
return a > b;//从大到小排序
}
};
使用:set<double,myComp> s;
自定义结构体:
struct Stu
{
string name;
string shcool;
bool operator < (const Stu &a)const//重载<排序
{
return a.name > name;
}
};
使用例程:
int main()
{
set<Stu> s;
Stu stu;
pair<set<Stu>::iterator, bool> r;
while (true)
{
cout << "name:" << endl;
cin >> stu.name;
cout << "school" << endl;
cin >> stu.shcool ;
if (stu.name == "dong")
break;
r = s.insert(stu);
if (!r.second)
cout << stu.name << "duplicated" << endl;
}
c++ stl容器set成员函数:find()--返回一个指向被查找到元素的迭代器
int main()
{
set<int> s;
s.insert(5); //第一次插入5,可以插入
s.insert(1);
s.insert(6);
s.insert(3);
s.insert(5); //第二次插入5,重复元素,不会插入
set<int>::iterator it;
it = s.find(6); //查找键值为6的元素
if (it != s.end())
cout << *it << endl;
else
cout << "not find it" << endl;
it = s.find(20);
if (it != s.end())
cout << *it << endl;
else
cout << "not find it" << endl;
return 0;
}
其他set函数大全:
c++ stl容器set成员函数:begin()--返回指向第一个元素的迭代器
c++ stl容器set成员函数:clear()--清除所有元素
c++ stl容器set成员函数:count()--返回某个值元素的个数
c++ stl容器set成员函数:empty()--如果集合为空,返回true
c++ stl容器set成员函数:end()--返回指向最后一个元素的迭代器
c++ stl容器set成员函数:equal_range()--返回集合中与给定值相等的上下限的两个迭代器
c++ stl容器set成员函数:erase()--删除集合中的元素
c++ stl容器set成员函数:get_allocator()--返回集合的分配器
c++ stl容器set成员函数:insert()--在集合中插入元素
c++ stl容器set成员函数:lower_bound()--返回指向大于(或等于)某值的第一个元素的迭代器
c++ stl容器set成员函数:key_comp()--返回一个用于元素间值比较的函数
c++ stl容器set成员函数:max_size()--返回集合能容纳的元素的最大限值
c++ stl容器set成员函数:rbegin()--返回指向集合中最后一个元素的反向迭代器
c++ stl容器set成员函数:rend()--返回指向集合中第一个元素的反向迭代器
c++ stl容器set成员函数:size()--集合中元素的数目
c++ stl容器set成员函数:swap()--交换两个集合变量
c++ stl容器set成员函数:upper_bound()--返回大于某个值元素的迭代器
c++ stl容器set成员函数:value_comp()--返回一个用于比较元素间的值的函数
insert(key_value); 将key_value插入到set中 ,返回值是pair<set<int>::iterator,bool>,bool标志着插入是否成功,而iterator代表插入的位置,若key_value已经在set中,则iterator表示的key_value在set中的位置。inset(first,second);将定位器first到second之间的元素插入到set中,返回值是void.
lower_bound(key_value) ,返回第一个大于等于key_value的定位器
upper_bound(key_value),返回第一个大于key_value的定位器
2.映射map的应用
(
1)基础特点
关联的本质在于元素的值与某个特定的键相关联,而并非通过元素在数组中的位置类获取。它的特点是增加和删除节点对迭代器的影响很小,除了操作节点,对其他的节点都没有什么影响。对于迭代器来说,不可以修改键值,只能修改其对应的实值。
自动建立Key - value的对应。key 和 value可以是任意你需要的类型,
但是需要注意的是对于key的类型,唯一的约束就是必须支持<操作符。
map中定义了以下三个类型:
- map<K, V>::key_type : 表示map容器中,索引的类型;
- map<K, V>::mapped_type : 表示map容器中,键所关联的值的类型;
- map<K, V>::value_type : 表示一个pair类型,它的first元素具有const map<K, V>::key_type类型,而second元素则有map<K, V>::mapped_type类型
对迭代器进行解引用时,将获得一个引用,指向容器中一个value_type类型的值,
对于map容器,其value_type是pair类型。
根据key值快速查找记录,查找的复杂度基本是Log(N),如果有1000个记录,最多查找10次,1,000,000个记录,最多查找20次。
(2)在map中添加元素一般有两种方法
/1/通过访问下标添加
courses["C"] = 14;
如果[key_value]中的key_value没有找到,就会创建一个新的,这也是和vector等最大的不同。
/2/map容器提供的insert操作:
1. map.insert(e) : e是一个用在map中的value_type类型的值。如果键不存在,则插入一个值为e.second的新元素;如果键在map中已经存在,那么不进行任何操作。该函数返回一个pair类型,该pair类型的first元素为当前插入e的map迭代器,pair的second类型是一个bool类型,表示是否插入了该元素。
2. map.insert(beg, end) : beg和end是迭代器,返回void类型
3. map.insert(iter, e) : e是value_type类型的值,如果e.first不在map中,则创建新元素,并以迭代器iter为起点搜索新元素存储的位置,返回一个迭代器,指向map中具有给定键的元素。
添加元素代码示例:
typedef pair<string,int> Map;
Map mm;
mm.first = "C++";
mm.second = 12;
map<string, int> courses;
map<string, int> courses2;
map<string, int>::iterator iter;
courses["C"] = 14;
courses.insert(map<string, int>::value_type("VB", 6));
courses.insert(make_pair("EDA",4));
courses.insert(mm);
courses.insert(courses2.begin(),courses2.end());
courses.insert(iter,mm);//如果mm.first不存在就插入成功,以iter为起点寻找创建新元素的地址
(3)删除元素
iterator erase(iterator it); //通过一个条目对象删除
iterator erase(iterator first, iterator last); //删除一个范围
size_type erase(const Key& key); //通过关键字删除
(4)查找元素
- 用find函数来定位数据出现位置,它返回的一个迭代器,当数据出现时,它返回数据所在位置的迭代器,如果map中没有要查找的数据,它返回的迭代器等于end函数返回的迭代器。
- 用count函数来判定关键字是否出现,无法定位数据出现位置,因为map的key都是唯一的,所以找到的话返回1,不然就返回0。
(5)其他操作函数
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器
get_allocator() 返回map的配置
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
转自Boblim
4.多重映射multimap和多重集合multiset
(1)基本特点
multimap和multiset 所支持的操作分别与map和set 操作相同,只有一个例外:multimap 不支持下标操作。不能对multimap对象使用下标操作,引用在这类容器中,某个键可能对应多个值。
(2)添加元素
multi系列的最大特点就是key值可以重复,例如可以像下面这样添加
courses.insert(make_pair("EDA",4));
courses.insert(make_pair("EDA", 12));
courses.insert(make_pair("EDA", 5));
courses.insert(make_pair("EDA", 6));
(3)删除元素
courses.erase("EDA");//带有一个键参数的erase版本将删除拥有该键的所有元素,并返回删除元素的个数。
iterator erase(iterator it);
iterator erase(iterator first, iterator last); //而带有一个或一对迭代器参数的版本只删除指定的元素,并返回void类型
(4)元素的查找
a.使用find和count操作
count 函数求出某键出现的次数,find 操作返回一个迭代器,指向第一个拥有正在查找的键。
实例:
int count = courses2.count("EDA");
multimap<string, string>::iterator iter;
iter = courses2.find("EDA");
b.调用lower_bound 和upper_bound将产生一个迭代器范围,指示出该键所关联的所有元素。
实例:
typedef multimap<string,string>::iterator it;it Beg=authors.lower_bound(search_item);it End=authors.upper_bound(search_item);
c.equal_range函数
equal_range函数返回存储一对迭代器的pair对象。如果该值存在,则pair对象中的第一个迭代器指向该键关联的第一个实例,第二个迭代器指向该键关联的最后一个实例的下一个位置。如果找不到匹配的元素,则pair对象中的两个迭代器都将指向此键应该插入的位置。
实例:
pair<it,it> pos=authors.equal_range("EDA");//定义一个pair 类型,该类型存放的都是迭代器while(pos.first!=pos.second){//pair的第一个成员不等于第二个成员,即两个迭代器不等 cout<<pos.first->second<<endl; ++pos.first;}