📌  相关文章
📜  unordered_multiset及其用法

📅  最后修改于: 2021-05-26 00:58:19             🧑  作者: Mango

在上一篇文章中我们讨论了unordered_set的问题,unordered_set的问题在于,不可能在该数据结构中存储重复的条目。例如,如果我们在unordered_set中已经有一些值v,那么再次插入v将无效。
要处理此重复,应使用unordered_mulitset,它也可以存储重复的元素。在内部,当插入现有值时,数据结构将增加其计数,该计数与每个值相关。由于每个值的计数存储在unordered_multiset中,因此比unordered_set占用更多的空间(如果所有值都是不同的)。
unordered_multiset的内部实现与unordered_set的内部实现相同,并且还使用哈希表进行搜索,只是计数值与前一个值相关联。由于元素的散列,它没有存储元素的特定顺序,因此所有元素可以任何顺序出现,但重复元素在一起。 unordered_multiset上的所有操作平均需要花费固定时间,但在最坏的情况下可以线性化。
Unordered_multiset支持许多功能,这些函数在下面的代码中演示:

// C++ program to demonstrate various function
// of unordered_multiset
#include 
using namespace std;
  
// making typedef for short declaration
typedef unordered_multiset::iterator umit;
  
// Utility function to print unordered_multiset
void printUset(unordered_multiset ums)
{
    //  begin() returns iterator to first element of set
    umit it = ums.begin();
    for (; it != ums.end(); it++)
        cout << *it << " ";
    cout << endl;
}
  
//  Driver program to check all function
int main()
{
    //  empty initialization
    unordered_multiset ums1;
  
    //  Initialization by intializer list
    unordered_multiset ums2 ({1, 3, 1, 7, 2, 3,
                                   4, 1, 6});
  
    //  Initialization by assignment
    ums1 = {2, 7, 2, 5, 0, 3, 7, 5};
  
    //  empty() function return true if set is empty
    // otherwise false
    if (ums1.empty())
        cout << "unordered multiset 1 is empty\n";
    else
        cout << "unordered multiset 1 is not empty\n";
  
    //  size() function returns total number of elements
    // in data structure
    cout << "The size of unordered multiset 2 is : "
         << ums2.size() << endl;
  
    printUset(ums1);
  
    ums1.insert(7);
  
    printUset(ums1);
  
    int val = 3;
  
    // find function returns iterator to first position
    // of  val, if exist otherwise it returns iterator
    // to end
    if (ums1.find(val) != ums1.end())
        cout << "unordered multiset 1 contains "
             << val << endl;
    else
        cout << "unordered multiset 1 does not contains "
             << val << endl;
  
    //  count function returns total number of occurrence in set
    val = 5;
    int cnt = ums1.count(val);
    cout << val << " appears " << cnt
         << " times in unordered multiset 1 \n";
  
    val = 9;
  
    //  if count return >0 value then element exist otherwise not
    if (ums1.count(val))
        cout << "unordered multiset 1 contains "
             << val << endl;
    else
        cout << "unordered multiset 1 does not contains "
             << val << endl;
  
    val = 1;
  
    // equal_range returns a pair, where first is iterator
    // to first position of val and second it iterator to
    // last position to val
    pair erange_it = ums2.equal_range(val);
    if (erange_it.first != erange_it.second)
        cout << val << " appeared atleast once in "
                        "unoredered_multiset \n";
  
  
    printUset(ums2);
  
    // erase function deletes all instances of val
    ums2.erase(val);
  
    printUset(ums2);
  
    // clear function deletes all entries from set
    ums1.clear();
    ums2.clear();
  
    if (ums1.empty())
        cout << "unordered multiset 1 is empty\n";
    else
        cout << "unordered multiset 1 is not empty\n";
}

输出 :

unordered multiset 1 is not empty
The size of unordered multiset 2 is : 9
3 0 5 5 7 7 2 2 
3 0 5 5 7 7 7 2 2 
unordered multiset 1 contains 3
5 appears 2 times in unordered multiset 1 
unordered multiset 1 does not contains 9
1 appeared atleast once in unoredered_multiset 
6 4 2 7 3 3 1 1 1 
6 4 2 7 3 3 
unordered multiset 1 is empty

如我们所见,大多数操作工作都类似于unordered_set,但需要注意的一些事情是:
equal_range(val)函数返回一对数据类型,其中第一个迭代器指向val的第一个位置,第二个迭代器指向val的最后一个位置。
例如,如果某个值v已在unordered_multiset中出现t次,并且调用了擦除操作,则v将被完全删除,这通常不是预期的行为,因此delete(val)函数将从数据结构中删除其所有实例。

通过使用find函数和擦除的迭代器版本,我们只能删除某个值的一个副本,因为find函数将迭代器返回到找到值的第一个位置,我们可以传递此迭代器来擦除而不是实际值,从而仅删除一个副本,如下所示:

//  C++ program to delete one copy from unordered set
#include 
using namespace std;
  
//  making typedef for short declaration
typedef unordered_multiset::iterator umit;
  
//  Utility function to print unordered_multiset
void printUset(unordered_multiset ums)
{
    // begin() returns iterator to first element of
    // set
    umit it = ums.begin();
    for (; it != ums.end(); it++)
        cout << *it << " ";
    cout << endl;
}
  
//  function to delete one copy of val from set
void erase_one_entry(unordered_multiset& ums,
                    int val)
{
    //  find returns iterator to first position
    umit it = ums.find(val);
  
    //  if element is there then erasing that
    if (it != ums.end())
       ums.erase(it);
}
  
//  Driver program to check above function
int main()
{
    //  initializing multiset by initializer list
    unordered_multiset ums ({1, 3, 1, 7, 2, 3,
                                 4, 1, 6});
  
    int val = 1;
    printUset(ums);
    erase_one_entry(ums, val);
    printUset(ums);
}

输出 :

6 4 2 7 3 3 1 1 1 
6 4 2 7 3 3 1 1 

unordered_multiset的方法:

  • insert()–在unordered_multiset中插入新元素。因此增加了容器的尺寸。
  • begin()–返回一个迭代器,该迭代器指向容器中的第一个元素或其存储桶中的第一个元素。
  • end()–返回一个迭代器,该迭代器指向容器中最后一个元素之后的位置,或者指向其存储桶中最后一个元素之后的位置。
  • empty()–如果unordered_multiset容器为空,则返回true。否则,它返回false。
  • find()–返回一个迭代器,该迭代器指向具有元素val的位置。
  • cbegin()–返回一个常量迭代器,该迭代器指向容器中的第一个元素或其存储桶中的第一个元素。
  • cend()–返回一个常量迭代器,该常量迭代器指向容器中最后一个元素之后的位置,或者指向其存储桶中最后一个元素之后的位置。
  • equal_range()–返回所有元素都等于给定值的范围。
  • emplace()–在unordered_multiset容器中插入一个新元素。
  • clear()–清除unordered_multiset容器的内容。
  • count()–返回unordered_multiset容器中等于给定值的元素计数。
  • size()– unordered_multiset的size()方法用于计算调用它的unordered_set的元素数。
  • max_size – unordered_multiset的max_size()获取unordered_multiset容器能够容纳的最大元素数。
  • swap()–交换两个unordered_multiset容器的内容。
  • 擦除()–用于删除单个元素或具有确定值的所有元素,或从开始(包括)到结束(不包括)的一系列元素。
  • bucket()–返回给定元素所在的存储桶编号。值区大小从0到bucket_count-1不等。
  • bucket_size()–返回存储桶中具有元素val的元素数。
  • reserve()– unordered_multiset的reverse()函数将容器中的存储桶数(bucket_count)设置为最适合包含至少n个元素的存储桶。
  • max_bucket_count()–返回无序多集容器可以具有的最大存储桶数。
  • load_factor()–返回unordered_multiset容器中的当前负载系数。
  • max_load_factor()–返回unordered_multiset容器的最大加载因子。
  • bucket_count()–返回unordered_multiset容器中的存储桶总数。
  • hash_function()–此哈希函数是一元函数,仅接受单个参数,并基于该参数返回一个唯一的大小为size_t的值。
  • rehash()–将容器中的存储桶数设置为N或更多。
  • key_eq()–根据比较结果返回布尔值。
  • emplace_hint()–在unordered_multiset容器中插入一个新元素。
  • get_allocator –此函数获取存储的分配器对象并返回用于构造容器的分配器对象。
  • 运算符= –’=’是C++ STL中的运算符,它将unordered_multiset复制(或移动)到另一个unordered_multiset和unordered_multiset :: 运算符=是相应的运算符函数。
要从最佳影片策划和实践问题去学习,检查了C++基础课程为基础,以先进的C++和C++ STL课程基础加上STL。要完成从学习语言到DS Algo等的更多准备工作,请参阅“完整面试准备课程”