允许重复:
我们在上一篇文章中讨论过unordered_map,但是有一个限制,我们不能在unordered_map中存储重复项,也就是说,如果我们在unordered_multimap中已经有一个键值对,并且已经插入了另一个键值对,那么两者都将存在,而在在unordered_map的情况下,对应于该键的先前值由仅会存在的新值更新。甚至可以在unordered_multimap中存在两次。
内部代表:
unordered_multimap的内部实现与unordered_map的内部实现相同,但是对于重复键,每个键值对都维护另一个计数值。由于对存储在哈希表中,因此它们之间没有特定的顺序,但是具有相同键的对在数据结构中会聚在一起,而具有相同值的对不能保证会聚在一起。
时间复杂度:
unordered_multimap上的所有操作平均需要花费恒定的时间,但在最坏的情况下,时间可能变为线性,具体取决于内部使用的哈希函数,但从长远来看,unordered_multimap的性能要优于multimap(基于树的multimap)。
职能:
unordered_multimap支持许多功能,这些功能在下面的代码中演示:
CPP
// C++ program to demonstrate various function of
// unordered_multimap
#include
using namespace std;
// making typedef for short declaration
typedef unordered_multimap::iterator umit;
// Utility function to print unordered_multimap
void printUmm(unordered_multimap 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 umm1;
// Initialization bu intializer list
unordered_multimap 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 and \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";
}
C++
// C++ program to implement find and erase for specific
// key-value pair for unordered_multimap
#include
using namespace std;
// making typedef for short declaration
typedef unordered_multimap::iterator umit;
// function to check whether p is there in map or not
bool find_kv(unordered_multimap& umm,
pair p)
{
// equal_range returns pair of iterator of first and
// last position associated with key
pair it = umm.equal_range(p.first);
umit it1 = it.first;
pair 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& umm,
pair p)
{
// equal_range returns pair of iterator of first and
// last position associated with key
pair it = umm.equal_range(p.first);
umit it1 = it.first;
pair 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 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 umm({ { "apple", 1 },
{ "ball", 2 },
{ "apple", 10 },
{ "cat", 7 },
{ "dog", 9 },
{ "cat", 6 },
{ "apple", 1 } });
cout << "Initial content\n";
printUmm(umm);
pair kv = make_pair("apple", 1);
// inserting one more pair
umm.insert({ "apple", 1 });
cout << "\nAfter insertion of one more \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 \n";
printUmm(umm);
}
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
After insertion of and
After deletion of apple
unordered multimap 2 is empty
正如我们在上面的代码中看到的那样,大多数操作的工作方式与unordered_map类似,但需要注意一些事项:
我们可以使用初始化列表来一次初始化和插入许多对。
unordered_multimap没有[]运算符,因为与键相对应的值不是唯一的,并且与一个键关联的值可能很多,因此[]运算符不能应用于它们。
擦除函数删除与提供的键关联的值的所有实例。
Find函数将迭代器返回到与该键关联的所有对中的键-值对的任何实例。
如何访问/删除密钥的特定值?
如果要检查是否存在特定项,则需要遍历与k对应的所有键值对,以类似的方式可以从数据结构中擦除特定项的一个副本。没有指定键的所有值的存储顺序。
C++
// C++ program to implement find and erase for specific
// key-value pair for unordered_multimap
#include
using namespace std;
// making typedef for short declaration
typedef unordered_multimap::iterator umit;
// function to check whether p is there in map or not
bool find_kv(unordered_multimap& umm,
pair p)
{
// equal_range returns pair of iterator of first and
// last position associated with key
pair it = umm.equal_range(p.first);
umit it1 = it.first;
pair 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& umm,
pair p)
{
// equal_range returns pair of iterator of first and
// last position associated with key
pair it = umm.equal_range(p.first);
umit it1 = it.first;
pair 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 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 umm({ { "apple", 1 },
{ "ball", 2 },
{ "apple", 10 },
{ "cat", 7 },
{ "dog", 9 },
{ "cat", 6 },
{ "apple", 1 } });
cout << "Initial content\n";
printUmm(umm);
pair kv = make_pair("apple", 1);
// inserting one more pair
umm.insert({ "apple", 1 });
cout << "\nAfter insertion of one more \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 \n";
printUmm(umm);
}
Initial content
After insertion of one more
After deletion one occurrence of
unordered_multimap的方法:
- begin()–返回一个迭代器,该迭代器指向容器中的第一个元素或其存储桶中的第一个元素。
- end()–返回一个迭代器,该迭代器指向容器中最后一个元素之后的位置,或者指向其存储桶中最后一个元素之后的位置。
- count()–返回容器中其键等于在参数中传递的键的元素数。
- cbegin()–返回一个常量迭代器,该迭代器指向容器中的第一个元素或其存储桶中的第一个元素。
- cend()–返回一个常量迭代器,该常量迭代器指向容器中最后一个元素之后的位置,或者指向其存储桶中最后一个元素之后的位置。
- clear()–清除unordered_multimap容器的内容。
- size()–返回unordered_multimap的大小。它表示该容器中元素的数量。
- swap()–交换两个unordered_multimap容器的内容。两个容器的尺寸可能不同。
- find()–返回一个迭代器,该迭代器指向具有键k的元素之一。
- bucket_size()–返回存储桶n中的元素数。
- empty()–如果unordered_multimap容器为空,则返回true。否则,它返回false。
- equal_range()–返回所有元素键等于一个键的范围。
- 运算符= –从其他容器复制/分配/移动元素。
- max_size()–返回unordered_multimap容器可以容纳的最大元素数。
- load_factor()–返回unordered_multimap容器中的当前负载系数。
- key_eq()–根据比较结果返回布尔值。
- emplace()–在unordered_multimap容器中插入新的{key,element}。
- emplace_hint()–在unordered_multimap容器中插入一个新的{key:element}。
- bucket_count()–返回unordered_multimap容器中的存储桶总数。
- bucket()–返回给定密钥所在的存储桶编号。
- max_load_factor()–返回unordered_multimap容器的最大加载因子。
- rehash()–将容器中的存储桶数设置为N或更多。
- reserve()–将容器中的存储桶数(bucket_count)设置为最合适的数量,以使其至少包含n个元素。
- hash_function()–此哈希函数是一元函数,仅接受单个参数,并根据该参数返回size_t类型的唯一值。
- max_bucket_count()–返回无序多图容器可以具有的最大存储桶数。