STL-24 unordered_multimap and its application(Introduced in C++11)

unordered_multimap and its application(Introduced in C++11)

Allows Duplicates:

I have discussed unordered_map in my previous post, but there is a limitation, we can not store duplicates in unordered_map, that is if we have a key-value pair already in our unordered_multimap and another pair is inserted, then both will be there whereas in case of unordered_map the previous value corresponding to the key is updated by the new value that is only would be there. Even can exist in unordered_multimap twice.

Internal Representation:

The internal implementation of unordered_multimap is the same as that of unordered_map but for duplicate keys, another count value is maintained with each key-value pair. As pairs are stored in the hash table, there is no particular order among them but pair with same keys come together in data structure whereas pair with same values are not guaranteed to come together.

Time Complexity:

All operation on unordered_multimap takes a constant amount of time on an average but time can go to linear in the worst case depending on internally used hash function but in long run unordered_multimap outperforms multimap (tree-based multimap).

Functions:

unordered_multimap supports many functions which are demonstrated in the below code :

// C++ program to demonstrate various function of
// unordered_multimap
#include <bits/stdc++.h>
using namespace std;

// making typedef for short declaration
typedef unordered_multimap<string, int>::iterator umit;

// Utility function to print unordered_multimap
void printUmm(unordered_multimap<string, int> umm) {
	// begin() returns iterator to first element of map
	umit it = umm.begin();

	for (; it != umm.end(); it++)
		cout << "<" << it->first << ", " << it->second
			<< "> ";

	cout << endl;
}

// Driver code
int main() {
	// empty initialization
	unordered_multimap<string, int> umm1;

	// Initialization bu intializer list
	unordered_multimap<string, int> umm2(
		{ { "apple", 1 },
		{ "ball", 2 },
		{ "apple", 10 },
		{ "cat", 7 },
		{ "dog", 9 },
		{ "cat", 6 },
		{ "apple", 1 } });

	// Initialization by assignment operation
	umm1 = umm2;
	printUmm(umm1);

	// empty returns true, if container is empty else it
	// returns false
	if (umm2.empty())
		cout << "unordered multimap 2 is empty\n";
	else
		cout << "unordered multimap 2 is not empty\n";

	// size returns total number of elements in container
	cout << "Size of unordered multimap 1 is "
		<< umm1.size() << endl;

	string key = "apple";

	// find and return any pair, associated with key
	umit it = umm1.find(key);
	if (it != umm1.end()) {
		cout << "\nkey " << key << " is there in unordered "
			<< " multimap 1\n";
		cout << "\none of the value associated with " << key
			<< " is " << it->second << endl;
	}
	else
		cout << "\nkey " << key
			<< " is not there in unordered"
			<< " multimap 1\n";

	// count returns count of total number of pair
	// associated with key
	int cnt = umm1.count(key);
	cout << "\ntotal values associated with " << key
		<< " are " << cnt << "\n\n";

	printUmm(umm2);

	// one insertion by makeing pair explicitly
	umm2.insert(make_pair("dog", 11));

	// insertion by initializer list
	umm2.insert({ { "alpha", 12 }, { "beta", 33 } });
	cout << "\nAfter insertion of <apple, 12> and <beta, "
			"33>\n";
	printUmm(umm2);

	// erase deletes all pairs corresponding to key
	umm2.erase("apple");
	cout << "\nAfter deletion of apple\n";
	printUmm(umm2);

	// clear deletes all pairs from container
	umm1.clear();
	umm2.clear();

	if (umm2.empty())
		cout << "\nunordered multimap 2 is empty\n";
	else
		cout << "\nunordered multimap 2 is not empty\n";
}

Output

<dog, 9>  <cat, 6>  <cat, 7>  <ball, 2>  <apple, 1>  <apple, 10>  <apple, 1>  
unordered multimap 2 is not empty
Size of unordered multimap 1 is 7

key apple is there in unordered  multimap 1

one of the value associated with apple is 1

total values associated with apple are 3

<dog, 9>  <cat, 6>  <cat, 7>  <ball, 2>  <apple, 1>  <apple, 10>  <apple, 1>  

After insertion of <apple, 12> and <beta, 33>
<alpha, 12>  <dog, 11>  <dog, 9>  <beta, 33>  <cat, 6>  <cat, 7>  <ball, 2>  <apple, 1>  <apple, 10>  <apple, 1>  

After deletion of apple
<alpha, 12>  <dog, 11>  <dog, 9>  <beta, 33>  <cat, 6>  <cat, 7>  <ball, 2>  

unordered multimap 2 is empty

As we can see in above code most of the operation work similar to unordered_map but some things to note are :
We can use the initializer list for initializing and inserting many pairs at once.
There is no [] operator for unordered_multimap because values corresponding to a key are not unique, there can be many values associated with a single key so [] operator can not be applied to them.
Erase function deletes all instances of values associated with the supplied key.
Find function returns an iterator to any instance of key-value pair among all pairs associated with that key.

How to access/delete if a specific value for a key?

If we want to check whether a specific is there or not, we need to loop over all pairs of key-value corresponding to k, in a similar way we can erase one copy of a specific from the data structure. There is no specified order in which all values of a key are stored.

// C++ program to implement find and erase for specific
// key-value pair for unordered_multimap
#include <bits/stdc++.h>
using namespace std;

// making typedef for short declaration
typedef unordered_multimap<string, int>::iterator umit;

// function to check whether p is there in map or not
bool find_kv(unordered_multimap<string, int>& umm, pair<string, int> p){
	// equal_range returns pair of iterator of first and
	// last position associated with key
	pair<umit, umit> it = umm.equal_range(p.first);
	umit it1 = it.first;

	pair<string, int> tmp;

	// looping over all values associated with key
	while (it1 != it.second) {
		tmp = *it1;
		if (tmp == p)
			return true;
		it1++;
	}
	return false;
}

// function to delete one copy of pair p from map umm
void erase_kv(unordered_multimap<string, int>& umm, pair<string, int> p) {
	// equal_range returns pair of iterator of first and
	// last position associated with key
	pair<umit, umit> it = umm.equal_range(p.first);
	umit it1 = it.first;
	pair<string, int> tmp;

	// looping over all values associated with key
	while (it1 != it.second) {
		tmp = *it1;
		if (tmp == p) {
			// iterator version of erase : deletes pair
			// at that position only
			umm.erase(it1);
			break;
		}
		it1++;
	}
}

// Utility function to print unordered_multimap
void printUmm(unordered_multimap<string, int> umm) {
	// begin() returns iterator to first element of map
	umit it = umm.begin();
	for (; it != umm.end(); it++)
		cout << "<" << it->first << ", " << it->second
			<< "> ";
	cout << endl;
}

// Driver code
int main() {
	// initializing multimap by initializer list
	unordered_multimap<string, int> umm({ { "apple", 1 },
										{ "ball", 2 },
										{ "apple", 10 },
										{ "cat", 7 },
										{ "dog", 9 },
										{ "cat", 6 },
										{ "apple", 1 } });

	cout << "Initial content\n";
	printUmm(umm);
	pair<string, int> kv = make_pair("apple", 1);

	// inserting one more <apple, 1> pair
	umm.insert({ "apple", 1 });
	cout << "\nAfter insertion of one more <apple, 1>\n";
	printUmm(umm);

	if (find_kv(umm, kv))
		erase_kv(umm, kv);
	else
		cout << "key-value pair is not there in unordered "
				"multimap\n";

	cout << "\nAfter deletion one occurrence of <apple, "
			"1>\n";
	printUmm(umm);
}

Output

Initial content
<dog, 9> <cat, 6> <cat, 7> <ball, 2> <apple, 1> <apple, 10> <apple, 1> 

After insertion of one more <apple, 1>
<dog, 9> <cat, 6> <cat, 7> <ball, 2> <apple, 1> <apple, 1> <apple, 10> <apple, 1> 

After deletion one occurrence of <apple, 1>
<dog, 9> <cat, 6> <cat, 7> <ball, 2> <apple, 1> <apple, 10> <apple, 1> 

Methods of unordered_multimap:

  • begin()– Returns an iterator pointing to the first element in the container or to the first element in one of its bucket.
  • end() – Returns an iterator pointing to the position after the last element in the container or to the position after the last element in one of its bucket.
  • count() – Returns the number of elements in the container whose key is equal to the key passed in the parameter.
  • cbegin() – Returns a constant iterator pointing to the first element in the container or to the first element in one of its bucket.
  • cend() – Returns a constant iterator pointing to the position after the last element in the container or to the position after the last element in one of its bucket.
  • clear() – Clears the contents of the unordered_multimap container.
  • size() – Returns the size of the unordered_multimap. It denotes the number of elements in that container.
  • swap() – Swaps the contents of two unordered_multimap containers. The sizes can differ of both the containers.
  • find() – Returns an iterator which points to one of the elements which have the key k.
  • bucket_size() – Returns the number of elements in the bucket n.
  • empty() – It returns true if the unordered_multimap container is empty. Otherwise, it returns false.
  • equal_range() – Returns the range in which all the element’s key is equal to a key.
  • operator= – Copy/Assign/Move elements from different container.
  • max_size() – Returns the maximum number of elements that the unordered_multimap container can hold.
  • load_factor() – Returns the current load factor in the unordered_multimap container.
  • key_eq() – Returns a boolean value according to the comparison.
  • emplace() – Inserts a new {key, element} in the unordered_multimap container.
  • emplace_hint() – Inserts a new {key:element} in the unordered_multimap container.
  • bucket_count() – Returns the total number of buckets in the unordered_multimap container.
  • bucket() – Returns the bucket number in which a given key is.
  • max_load_factor() – Returns the maximum load factor of the unordered_multimap container.
  • rehash() – Sets the number of buckets in the container to N or more.
  • reserve() – Sets the number of buckets in the container (bucket_count) to the most appropriate number so that it contains at least n elements.
  • hash_function() – This hash function is a unary function that takes a single argument only and returns a unique value of type size_t based on it.
  • max_bucket_count() – Returns the maximum number of buckets that the unordered multimap container can have.

For more detailed information, turn to Baidu or Google.

More about c++ STL, turn to this page.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值