关联容器:associative container
Abstract
关联容器的学习,C++ primer,第十章:关联容器(associative container)。
Introduction
继续对容器的学习,之前的资料没有整理。这里是自己所实践的学习代码,皮毛再见皮毛。
//********************************************************************
/*(C) Do what you can, with what you have, where you are.
Flie : associative.cpp
Path : D:\on the way to C++\0810_associative container
Author : Yung
E-mail : softpart@126.com
Date : 2013/8/10 13:47
Comment : C++ primer 第十章 关联容器
*///*********************************************************************
#include <iostream>
#include <utility> //pair类型所需要包含的文件
#include <string>
#include <map>
#include <algorithm>
#include <functional>
#include <vector>
#include <set>
using namespace std;
//关联容器类型
///<summary>
///map: 关联数组;元素通过键来存储和读取
///set: 大小可变的集合,支持通过键来实现快速的读取
///multimap: 支持同一个键多次出现的map类型
///multiset: 支持同一个键多次出现的set类型
///</summary>
int main()
{
//1、pair类型
//pair<T1, T2> p1;创建一个空的pair对象
//pair<T1, T2> p1(V1, V2): 创建一个pair对象,并使用V1,V2初始化
//eg:
//pair<string, string> p1;
//pair<string, int> p2;
//pair<string, vector<int> > p3;
//以上可以看出,T1和T2可以相同也可以不同
//pair使用详单繁琐,如果要定义多个相同的pair对象,可以考虑使用 typedef 简化声明
//eg:
typedef pair<string, int> people;
people one;
people two;
//pair的操作
//pair类可以直接访问其数据成员,其成员都是共有的,分别命名为first 和 second
//eg:
typedef pair<string, string> book;
book book1("金梅瓶","NB");
if (book1.first == "金梅瓶" && book1.second == "NB")
{
cout << "买下!!!" << endl;
}
//make.pair(V1, V2): 创建一个新的pair对象,其类型分别为V1和V2的类型;
pair<int, string> make_p = make_pair(1,"s");
//p1 < p2: 两个pair对象的小于运算,遵循字典的次序,若p1.first < p2.first 或者 p1.second < p2.second 则返回真。
//p1 == p2: 相等的运算
//int a11 = NULL*100;
//cout << a11 << endl;
//2、map对象:必须包含map头文件;在定义map对象时必须指明键和值的类型
map<string, int> member;
//map<V, K>::key_type 在map容器中,用做索引的键的类型
//map<V, K>::mapped_type 在map容器中,键所关联的值的类型
//map<V, K>::value_type 一个pair类型,它的first元素具有map<V, K>::key_type类型,它的second具有map<V, K>::mapped_type类型
//对map迭代器进行解引用将产生pair类型
//给map添加元素
//(1)下标操作
member["Yung"] ;
//首先查找是否有"Yung"这个键
//若没有,则插入,若没有指明值,则采用默认值0
//此时若指明值,则更新值
member["Yung"] = 1;
//此时因为这个键存在,故不执行插入的动作,值还是1
member["Yung"] ;
//此时,键不存在,故执行插入的动作,size增加1
member["Yung1"] ;
//迭代器返回的value_type类型(const key_type,mapped_type),而下标操作返回的是mapped_type类型
//(2)insert操作
member.insert(map<string, int>::value_type("Yung2",1));//1.创建一个新的pair对象,直接插入到map中
member.insert(make_pair("Yung3",1));//2.使用make_pair简化
typedef map<string, int>::value_type map_type;
member.insert(map_type("Yung4",1));//3.使用typedef简化
map<string, int>::iterator member_iter = member.begin();
cout << member_iter->first << " " << member_iter->second << endl;
//map对象中一个给定键只对应一个元素,若试图插入的键已经存在map中则insert不执行任何操作
//eg:
map<string, int> people1;
people1.insert(make_pair("Yung",26));
people1.insert(make_pair("Yung",23));
map<string, int>::iterator p_iter = people1.begin();
cout << "yes or no:" << p_iter->first << " " << p_iter->second << endl;
//检测insert的返回值:带有一个键-值的pair形参的insert版本将返回一个pair值:包含一个迭代器(key_type)和一个bool值
//迭代器:指向map中具有相应键的元素
//bool:返回是否插入成功
//eg:
pair<map<string, int>::iterator ,bool> ret = people1.insert(make_pair("Yung",21));
cout << "Key: " << ret.first->first << " " << ret.first->second << endl;
cout << "Bool: " << ret.second << endl;
//有时候我们需要的仅仅是查找是否存在key,并读出map元素,但是并不想插入,那么怎么办呢?
//就像上面所说的一样,下标操作可以获得元素,但是若key不在map中,就会新插入一个元素,TMD,这是扯淡的
//于是就有如下两个操作:
//m.count(K):返回m中k出现的次数
//m.find(K):若存在K索引的元素,则返回指向该元素的迭代器,若不存在则返回end
//eg:
map<string, int> m_People;
m_People.insert(make_pair("m_name",23));
m_People.insert(make_pair("m_name1",83));
m_People.insert(make_pair("m_name2",23));
//此时会返回1
cout << "m_People:" << m_People.count("m_name") << endl;
//此时会返回0
cout << "m_People:" << m_People.count("m_name的") << endl;
//于是可以说,对于map对象,count操作只能返回0或者1
map<string, int >::iterator n_iter = m_People.find("ni1ma");
if (n_iter != m_People.end())
{
cout << "你妹的:" << n_iter->first << " " << n_iter->second << endl;
}
else
cout << "你妹的,不存在!" << endl;
//(3)map删除元素:erase
//m.erase(K):删除m中键为k的元素,返回size_type类型的值,表示删除元素的个数
//m.erase(p):删除迭代器p所指向的元素,p必须是m中所存在的元素,并且p不能等于m.end(),返回void类型;
//m.erase(b, e):删除一段范围的元素
//eg:
//m.erase(K)
for(map<string, int>::iterator m_iter = m_People.begin(); m_iter != m_People.end(); m_iter++)
cout << "S:" << m_iter->first << " " << m_iter->second << endl;
m_People.erase("m_name");
for(map<string, int>::iterator m_iter = m_People.begin(); m_iter != m_People.end(); m_iter++)
cout << "S1:" << m_iter->first << " " << m_iter->second << endl;
//m.erase(p)
for(map<string, int>::iterator m_iter = m_People.begin(); m_iter != m_People.end(); m_iter++)
{
if (m_iter->first == "m_name1")
{
m_People.erase(m_iter++); //这里需要注意:更新迭代器
}
}
for(map<string, int>::iterator m_iter = m_People.begin(); m_iter != m_People.end(); m_iter++)
cout << "S2:" << m_iter->first << " " << m_iter->second << endl;
//继续强烈插入
m_People.insert(make_pair("m_name",23));
m_People.insert(make_pair("m_name1",83));
m_People.insert(make_pair("m_name2",23));
for(map<string, int>::iterator m_iter = m_People.begin(); m_iter != m_People.end(); m_iter++)
cout << "G:" << m_iter->first << " " << m_iter->second << endl;
//这样不可以
m_People.erase(m_People.begin(),m_People.end());
for(map<string, int>::iterator m_iter = m_People.begin(); m_iter != m_People.end(); m_iter++)
cout << "G1:" << m_iter->first << " " << m_iter->second << endl;
//再插三次
m_People.insert(make_pair("m_name",23));
m_People.insert(make_pair("m_name1",83));
m_People.insert(make_pair("m_name2",23));
for(map<string, int>::iterator m_iter = m_People.begin(); m_iter != m_People.end(); m_iter++)
cout << "H:" << m_iter->first << " " << m_iter->second << endl;
//客官,这样不可以
//m_People.erase(m_People.begin(),m_People.begin()+1);
m_People.erase(m_People.begin(),++m_People.begin());
// m_People.erase(m_People.begin(),++++m_People.begin());
for(map<string, int>::iterator m_iter = m_People.begin(); m_iter != m_People.end(); m_iter++)
cout << "H1:" << m_iter->first << " " << m_iter->second << endl;
//尼玛,这迭代器不支持算术运算
//再插三次
m_People.insert(make_pair("m_name",23));
m_People.insert(make_pair("m_name1",83));
m_People.insert(make_pair("m_name2",23));
//这里如何使用for_each语句呢?
for(map<string, int>::iterator m_iter = m_People.begin(); m_iter != m_People.end(); m_iter++)
cout << "I:" << m_iter->first << " " << m_iter->second << endl;
//换for_each来实现
//#include <algorithm>
void display(const pair<string,int> & p);
for_each(m_People.begin(), m_People.end(), display);
//#include <functional>
//好吧,再试试传入参数
void display_with_parameter(const pair<string,int> p, const string m);//为啥不能引用
for_each(m_People.begin(), m_People.end(), bind2nd(ptr_fun(display_with_parameter),"FUCK:"));
//3.set对象:单纯key的集合
//set:不支持下标操作,没有定义mapped_type类型。在set中value_type不是pair类型,而是与key_type相同类型,它们都是只得是set中存储元素的类型。
//set每个键都只能对应一个元素
//书上一个例子 P320
vector<int> ivec;
for (vector<int>::size_type i = 0; i != 10; ++i)
{
ivec.push_back(i);
ivec.push_back(i);
}
set<int> iset(ivec.begin(), ivec.end());
cout << "ivec:" << ivec.size() << endl;//20
cout << "iset:" << iset.size() << endl;//10
//(1)在set中添加元素
set<string> set1;
set1.insert("You");
set1.insert("Me");
//迭代器
set<int> iset1;
iset1.insert(ivec.begin(),ivec.end());
//(2)从set寻找元素
//获取元素 find
set<string>::iterator iter1 = set1.find("You");
cout << "set:" << *iter1 <<endl; //这里实际上需要注意迭代器范围
//仅仅想知道是否存在某一个元素
int get_num = set1.count("You");
cout << "set num:" << get_num <<endl;
int get_num2 = set1.count("You2");
cout << "set num2:" << get_num2 <<endl;
//关联容器还包括 multimap类型和multiset类型
return 0;
}
void display(const pair<string,int> & p)
{
cout << "I2:" << p.first << " " << p.second << endl;
}
void display_with_parameter(const pair<string,int> p, const string m)
{
cout << m << p.first << " " << p.second << endl;
}
<END>
浙公网安备 33010602011771号