STL—multimap

   multimap 是属于关联容器的一个(其它三个是map、set、multiset),关联容器的插入、删除和查找时间都相同,为O( log(N) 。在学习 multimap 之前最好得先对 map 和 pair 有一定的了解。

  multimap是一个允许有多个同键元素的map。其接口与map接口基本相同,只有以下几点改变:

 

  • multimap 没有提供operator[ ]。由于一个键可能对应多个元素,所以这个操作符没有意义。
  • multimap上的插入总会成功。因此,多映射(multimap)insert()增加一个元素时,并不需要返回 iterator 和 bool 的 pair 。它只返回 iterator 。

tips: multimaps 允许插入相同的键/值对。如果想避免这种冗余性,必须在插入新元素之前先显式做检查。

 

  multimap 最难得部分是查找元素。不能使用operator [ ] ,因为没有提供这个操作符。find()不是特别有用,因为它返回的 iterator 会指示有给定键值的任何元素(不一定是有该键的第一个元素)。

  幸运的是,multimap 会把所有带相同键的元素存储在一起,而且提供了一些方法来得到容器中同键元素子区间的相应 iterator。lower_bound( ) 和 upper_bound( ) 都返回一个 iterator ,分别指示第一个元素和越过最后元素的“元素”。如果不存在与该键匹配的元素,则 lower_bound( ) 和 upper_bound( ) 返回的 iterator 相等

   如果不想分别调用两个方法来得到界定给定键元素的 iterator ,multimap 还提供了一个 equal_range( ) 方法,它会返回 lower_bound( ) 和 upper_bound( ) 所返回两个 iterator 的一个 pair。

  下面的例子展示了这些方法的使用。

tips:lower_bound( )、upper_bound( ) 和 equal_range( ) 方法在 map 中也有,但是用途很有限。


   多映射示例:好友列表

  大多数在线聊天程序允许用户有一个“好友列表”或朋友列表。聊天程序会对好友列表中列出的用户授予特权,如允许他们向用户主动发送消息。

  为在线聊天程序实现好友列表的一种方法是把信息存储在一个 multimap 中。一个 multimap 可以存储所有用户的好友列表。容器中的每一项存储对应一个用户的好友。键是用户,值是好友。例如,“张三”和“李四”都在对方的好友列表中,那么就会有形式如下的两项:"张三"映射至“李四“和”李四“映射至”张三“。multimap 允许同一个键有多个值,因此一个用户可以有多个好友。以下是 BuddyList 类定义。

 

#include<map>

#include<string>

#include<list>



using std::multimap;

using std::string;

using std::list;



class BuddyList

{

public:

	BuddyList();



	//adds buddy as a friend of name 

    void addBuddy(const string& name,const string& buddy);



	//removes buddy as a friend of name 

	void removeBuddy(const string& name ,const string& buddy);



	//returns true if buddy is a friend of name,otherwise returns false

	bool isBuddy(const string& name,const string& buddy);



	//retrieves a list of all the friends name

	list<string> getBuddies(const string& name) const;

	

protected:

	multimap<string, string> mBuddies;



private:

	BuddyList(const BuddyList& src);

	BuddyList& operator=(const BuddyList&rhs);

};

 

 

  以下是实现。它展示了 lower_bound( )、upper_bound( ) 和 equal_range( ) 的使用。

 

#include "BuddyList.h"

using namespace std;



BuddyList::BuddyList()

{



}



void BuddyList::addBuddy(const string& name,const string& buddy)

{

	//make sure this buddy isn't already there,we don't want to insert a identical copy of the key/value pair.

	if(!isBuddy(name,buddy))

	{

		mBuddies.insert(make_pair(name, buddy));

	}

}



void BuddyList::removeBuddy(const string& name ,const string& buddy)

{

	//declare two iterators into the map.

	multimap<string, string>::iterator start, end;



	//obtain the beginning and end of the range of elements with key name.

	//use both lower_bound() and upper_bound() to demonstrate their use.

	//otherwise, could just call equal_range().

	//lower_bound()和upper_bound()都返回一个iterator,分别指示第一个元素和越过最后元素的“元素”。

	start = mBuddies.lower_bound(name);

	end = mBuddies.upper_bound(name);



	//iterate through the elements with key name looking for a value buddy

	for(start; start !=end; ++start)

	{

		//we found a match! remove it from the map

		if(start->second == buddy)

		{

		   mBuddies.erase(start);

		   break;

		}

	}

}



bool BuddyList::isBuddy(const string& name,const string& buddy)

{

	//declare two iterators into the map.

	multimap<string, string>::iterator start, end;



	//obtain the beginning and end of the range of elements with key name.

	//use both lower_bound() and upper_bound() to demonstrate their use.

	//otherwise, could just call equal_range().

	start =mBuddies.lower_bound(name);

	end = mBuddies.upper_bound(name);



	//iterate through the element with key name looking for a value buddy. if there

	//are no elements whit key name,start equals end,so the loop body doesn't execute.

	for(start; start!=end;++start)

		if(start->second ==buddy)

			//we found a match!

			return true;

		//no matchs

		return false;

}



list<string> BuddyList::getBuddies(const string& name) const

{

	//create a variable to store the pair of iterators.

	pair<multimap<string,string>::const_iterator,multimap<string,string>::const_iterator> its;



	//obtain the pair of iterators marking the range containing elements with key name.

	its = mBuddies.equal_range(name);



	//create a list with all the names in the range

	//(all the buddies of name)

	list<string> buddies;

	for(its.first; its.first !=its.second; ++its.first)

	{

		buddies.push_back((its.first)->second);

	}



	return buddies;

}


  要注意,removeBuddy( ) 不能只是使用 ”完全删除“ 版本的 erase ( ),即把有给定键的所有元素都删除,因为它应当只删除给定键的一个元素,而非全部。还有注意,getBuddies( )不能使用 list 的 insert( ) 在 equal_range( ) 返回的区间内插入元素,因为 multimap iterator 指示的元素是键/值对,而不是 string 。getBuddies( ) 必须显式地迭代处理 list ,从各个键/值抽取出 string ,并将其压入到待返回的新 list 中。

 

  以下是BuddyList 的一个简单测试。

 

#include "BuddyList.h"

#include<iostream>

using namespace std;



int main()

{

	BuddyList buddies;



	buddies.addBuddy("Harry Potter","Ron Weasley");

	buddies.addBuddy("Harry Potter","Hermione Granger");

	buddies.addBuddy("Harry Potter","Hagid");

	buddies.addBuddy("Harry Potter","Draco Malfoy");



	//That's not right! remove Draco

	buddies.removeBuddy("Harry Potter","Draco Malfoy");

	

	buddies.addBuddy("Hagrid","Harry Potter");

	buddies.addBuddy("Hagrid","Ron Weasley");

	buddies.addBuddy("Hagrid","Hermione Granger");



	list<string> harryBuds = buddies.getBuddies("Harry Potter");



	cout<<"Harry's friends:\n";

	for(list<string>::const_iterator it = harryBuds.begin();

	it != harryBuds.end(); ++it)

	{

		cout<<"\t"<<*it<<endl;

	}



	return 0;



}


  运行结果如下:

 

STL—multimap


以上代码下载链接:http://download.csdn.net/detail/chaoyuan899/5476205



 

你可能感兴趣的:(map)