set、multiset
概述
set 和 multiset 使得用户可以快速查找键(键是唯一存储在一维容器中的值)。二者区别:set只能存储唯一的值,multiset能存储重复值
set 和 multiset 的通过实现类似二叉树的内部结构进行排序,提高了查找速度。因此,这两种结构的特定位置元素不能被替换为值不同的新元素。
注意包含头文件:#include <set>
实例化
/*
desc:set/multiset的初始化
*/
#include <iostream>
#include <set>
using namespace std;
//指定排序标准
template <typename T>
struct SordDescending
{
bool operator() (const &T lsh, const &T rsh) const
{
return lsh > rsh;
}
};
int main()
{
// 1. 简单初始化(此时的默认排序谓词为:std::less<T>。升序为std::greater<T>)
set <int> setIntegers1;
multiset <int> mulsetIntegers1;
// 2. 带有用户自定义排序谓词的初始化
set <int, SordDescending<int>> setIntegers2;
multiset <int, SordDescending<int>> mulsetIntegers2;
// 3. 用另一个容器(或者该容器的一部分)来初始化
set <int> setIntegers3(setIntegers1);
multiset <int> mulsetIntegers(setIntegers1.cbegin(), setIntegers1.end());
system("pause");
return 0;
}
插入
#include <iostream>
#include <set>
using namespace std;
template <typename T>
void DisplayElement (const T& input)
{
for (auto iElementLocator = input.cbegin()
; iElementLocator != input.cend()
; ++iElementLocator)
{
cout << *iElementLocator << " ";
}
cout << endl;
}
int main()
{
set <int> setIntegers;
multiset <int> msetIntegers;
setIntegers.insert(60);
setIntegers.insert(-1);
setIntegers.insert(3000);
DisplayElement(setIntegers);
setIntegers.insert(3000);
cout << "Inserting the number 3000 again:" << endl;
DisplayElement(setIntegers);
msetIntegers.insert(setIntegers.begin(), setIntegers.end());
DisplayElement(msetIntegers);
msetIntegers.insert(3000);
cout << "The count of'3000' in multiset is: ";
cout << msetIntegers.count(3000) << endl;
system("pause");
return 0;
}
务必使用 multiset.count(value) 来确定有多少个元素包含特定的value值
查找
#include <set>
#include <iostream>
using namespace std;
int main()
{
//43 78 -1 124
set <int> setIntegers;
setIntegers.insert(43);
setIntegers.insert(78);
setIntegers.insert(-1);
setIntegers.insert(124);
for (auto iElement = setIntegers.begin(); iElement != setIntegers.end(); ++iElement)
{
cout << *iElement << " ";
}
cout << endl;
//通过成员函数:find()查找
auto iElementFound = setIntegers.find(1223);
if (iElementFound != setIntegers.end()) //实参可以换成set中存在的
{
cout << "Element " << *iElementFound << " found!" << endl;
}
else
{
cout << "Element not found in set!" << endl;
}
system("pause");
return 0;
}
find() 返回一个迭代器,指向找到的第一个元素。可将该迭代器递增以获取下一个元素。
删除
/*
通过成员函数:erase()
1. setObject.erase (key); // 根据键删除值
2. setObject.erase (element); // 迭代器作为参数,并删除该迭代器指向的对象
MSETINT::iterator elementFound = msetInts.find(numberToErase);
if (elementFound != msetInts.end ())
msetInts.erase (elementFound);
else
cout << "Element not found!" << endl;
3. setObject.erase (iLowerBound, iUpperBound); // 迭代器指定删除的边界
MSETINT::iterator elementFound = msetInts.find(valueToErase);
if (elementFound != msetInts.end ())
msetInts.erase (msetInts.begin (), elementFound);
*/
#include <set>
#include <iostream>
using namespace std;
template <typename T>
void DisplayElement (const T& input)
{
for (auto iElement = input.cbegin()
; iElement != input.cend()
; ++iElement)
{
cout << *iElement << " ";
}
cout << endl;
}
typedef multiset <int> MSETINT;
int main()
{
MSETINT msetIntegers;
msetIntegers.insert(43);
msetIntegers.insert(78);
msetIntegers.insert(78);
msetIntegers.insert(49);
msetIntegers.insert(124);
cout << "multiset contains " << msetIntegers.size() << " elements.";
cout << " These are: " << endl;
DisplayElement(msetIntegers);
cout << "Please enter a number to be erased from the set" << endl;
int nNumberToErase = 0;
cin >> nNumberToErase;
cout << "Erasing " << msetIntegers.count(nNumberToErase);
cout << " instances of value " << nNumberToErase << endl;
msetIntegers.erase(nNumberToErase);
cout << "multiset contains " << msetIntegers.size() << " elements: ";
DisplayElement(msetIntegers);
system("pause");
return 0;
}
通过 size() 指出容器包含多少个元素。
一个具体例子:存储对象的set(multiset)
#include <set>
#include <string>
#include <iostream>
using namespace std;
template <typename T>
void DisplayContents (const T& input)
{
for (auto iElement = input.cbegin()
; iElement != input.cend()
; ++iElement)
{
cout << *iElement << endl;
}
cout << endl;
}
struct ContactItem
{
string strContactsName;
string strPhoneNumber;
string strDisplayRepresentation;
ContactItem (const string& strName, const string& strNumber)
{
strContactsName = strName;
strPhoneNumber = strNumber;
strDisplayRepresentation = (strContactsName + ": " + strPhoneNumber);
}
bool operator == (const ContactItem& itemToCompare) const
{
return (itemToCompare.strContactsName == this->strContactsName);
}
bool operator < (const ContactItem& itemToCompare) const
{
return (this->strContactsName < itemToCompare.strContactsName);
}
operator const char*() const
{
return strDisplayRepresentation.c_str();
}
};
int main()
{
set <ContactItem> setContacts;
setContacts.insert(ContactItem("Jack Welsch", "+1 7889 879 879"));
setContacts.insert(ContactItem("Bill Gates", "+1 97 7897 8799 8"));
setContacts.insert(ContactItem("Angi Merkel", "+49 23456 5466"));
setContacts.insert(ContactItem("Vlad Putin", "+7 6645 4564 797"));
setContacts.insert(ContactItem("John Travolta", "91 234 4564 789"));
setContacts.insert(ContactItem("Ben Affleck", "+1 745 641 314"));
DisplayContents(setContacts);
cout << "Enter a person whose number you wish to delete: " ;
string deletename;
getline(cin, deletename);
auto iContactFound = setContacts.find(ContactItem(deletename, ""));
if (iContactFound != setContacts.end())
{
setContacts.erase(iContactFound);
cout << "After deleting: " << endl;
DisplayContents(setContacts);
}
else
{
cout << "Contact not found!" << endl;
}
system("pause");
return 0;
}
对于存储对象的set、multiset,一定要实现运算符 < 和 ==,前者用于排序,后者用于 set::find()
unordered_set、unordered_multiset
通过hash函数计算排序索引,根据索引决定将元素放到哪个桶(bucket)内。
使用时注意添加头文件:#include <unordered_set>
对于初始化、插入、查找、删除等操作与set类似,注意一个重要特征:
负责确定排列顺序的散列函数:
unordered_set<int>::hasher HFn = usetInt.hash_function();
一个具体例子:
#include <iostream>
#include <unordered_set>
using namespace std;
template <typename T>
void DisplayContents (const T& input)
{
cout << "Number of elements, size() = " << input.size() << endl;
cout << "Max bucket count = " << input.max_bucket_count() << endl;
cout << "Load factor: " << input.load_factor() << endl;
cout << "Max load factor = " << input.max_load_factor() << endl;
cout << "Unordered set contains: " << endl;
for (auto iElement = input.cbegin()
; iElement != input.cend()
; ++iElement)
{
cout << *iElement << " ";
}
cout << endl;
}
int main()
{
unordered_set <int> usetIntegers;
cout << usetIntegers.max_bucket_count() << endl;
cout << endl;
usetIntegers.insert(1000);
usetIntegers.insert(-3);
usetIntegers.insert(2011);
usetIntegers.insert(300);
usetIntegers.insert(-1000);
usetIntegers.insert(989);
usetIntegers.insert(-300);
usetIntegers.insert(111);
DisplayContents(usetIntegers);
usetIntegers.insert(999);
cout << endl;
cout << usetIntegers.max_bucket_count() << endl;
cout << endl;
DisplayContents(usetIntegers);
cout << "Enter int you want to check for existence in set: ";
int Key = 0;
cin >> Key;
auto iPairThousand = usetIntegers.find(Key);
if (iPairThousand != usetIntegers.cend())
{
cout << *iPairThousand << " found in set" << endl;
}
else
{
cout << Key << " not available in set" << endl;
}
system("pause");
return 0;
}