关联容器: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>

 

posted on 2013-08-13 16:36  从此无她不见月  阅读(213)  评论(0)    收藏  举报

导航