Использовать настройку, когда:
- Нам нужны упорядоченные данные (отдельные элементы).
- Мы должны были бы распечатать / получить доступ к данным (в отсортированном порядке).
- Нам нужен предшественник / преемник элементов.
Использовать unordered_set, когда:
- Нам нужно сохранить набор отдельных элементов, и упорядочение не требуется.
- Нам нужен одноэлементный доступ, т. Е. Обхода нет.
Примеры:
комплект:
Ввод: 1, 8, 2, 5, 3, 9
Выход: 1, 2, 3, 5, 8, 9
Unordered_set:
Ввод: 1, 8, 2, 5, 3, 9
Вывод: 9 3 1 8 2 5 (возможно, этот порядок зависит от хэш-функции)
В основном разница:
Примечание: (в некоторых случаях set
более удобно), например, используя vector
в качестве ключа
set<vector<int>> s;
s.insert({1, 2});
s.insert({1, 3});
s.insert({1, 2});
for(const auto& vec:s)
cout<<vec<<endl; // I have override << for vector
// 1 2
// 1 3
Причина, по которой vector<int>
может быть ключом set
, потому что vector
переопределить operator<
.
Но если вы используете unordered_set<vector<int>>
, вам нужно создать хеш-функцию для vector<int>
, потому что вектор не имеет хеш-функции, поэтому вы должны определить такую как:
struct VectorHash {
size_t operator()(const std::vector<int>& v) const {
std::hash<int> hasher;
size_t seed = 0;
for (int i : v) {
seed ^= hasher(i) + 0x9e3779b9 + (seed<<6) + (seed>>2);
}
return seed;
}
};
vector<vector<int>> two(){
//unordered_set<vector<int>> s; // error vector<int> doesn't have hash function
unordered_set<vector<int>, VectorHash> s;
s.insert({1, 2});
s.insert({1, 3});
s.insert({1, 2});
for(const auto& vec:s)
cout<<vec<<endl;
// 1 2
// 1 3
}
вы можете видеть, что в некоторых случаях unordered_set
сложнее.
В основном цитируется из:
https://www.geeksforgeeks.org/set-vs-unordered_set-c-stl/
https://stackoverflow.com/a/29855973/6329006