C ++ 0x는 다른 곳에서도 unordered_set
사용할 수있는 것을 소개 boost
합니다. 내가 이해하는 unordered_set
것은 O(1)
조회 복잡도 가있는 해시 테이블입니다 . 반면에 조회 복잡성이 set
있는 나무 log(n)
일뿐입니다. 왜 지구상에서 누군가 set
대신에 사용 unordered_set
하겠습니까? 즉 set
더 이상 필요 합니까?
C ++ 0x는 다른 곳에서도 unordered_set
사용할 수있는 것을 소개 boost
합니다. 내가 이해하는 unordered_set
것은 O(1)
조회 복잡도 가있는 해시 테이블입니다 . 반면에 조회 복잡성이 set
있는 나무 log(n)
일뿐입니다. 왜 지구상에서 누군가 set
대신에 사용 unordered_set
하겠습니까? 즉 set
더 이상 필요 합니까?
답변:
세트의 항목을 반복하려는 사람의 경우 순서가 중요합니다.
< >
됩니까?
정렬되지 않은 세트는 몇 가지 방법으로 O (1) 평균 액세스 시간을 지불해야합니다.
set
사용 적은 메모리 보다 unordered_set
같은 수의 요소를 저장하도록한다.set
할 수있는 빠른 에서 조회보다 unordered_set
.unordered_set
, 그들은 종종이 보장되는 더 나은 최악의 복잡성을 위해 set
(예를 들어 insert
).set
종류의 요소는 당신이 순서에 액세스 그들에게 원하는 경우 유용합니다.set
과들 <
, <=
, >
과 >=
. unordered_set
이러한 작업을 지원할 필요는 없습니다.<
)가 아닌 평등 비교 만 표시 됩니다.
해시 테이블보다 트리를 선호 할 때마다.
예를 들어, 해시 테이블은 최악의 경우 "O (n)"입니다. O (1)이 평균 사례입니다. 나무는 최악의 경우 "O ( log n)"입니다.
다음과 같은 경우에 세트를 사용하십시오.
다음과 같은 경우 unorder_set을 사용하십시오.
예 :
세트:
입력 : 1, 8, 2, 5, 3, 9
출력 : 1, 2, 3, 5, 8, 9
정렬되지 않은 _ 세트 :
입력 : 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
std :: set은 Standard C ++의 일부이고 unorder_set은 그렇지 않기 때문입니다. C ++ 0x는 표준이 아니며 Boost도 아닙니다. 우리 중 많은 사람들에게 이식성은 필수적이며 이는 표준을 고수한다는 의미입니다.
스위프 라인 알고리즘을 고려하십시오. 이 알고리즘은 해시 테이블에서 완전히 실패하지만 균형 트리에서 아름답게 작동합니다. 스위프 라인 알고리즘의 구체적인 예를 제공하려면 fortune의 알고리즘을 고려하십시오. http://en.wikipedia.org/wiki/Fortune%27s_algorithm
g++
6.4 stdlibc ++ 주문과 비 정렬 세트 벤치 마크
이 주요 Linux C ++ 구현을 벤치마킹하여 차이점을 확인했습니다.
전체 벤치 마크 세부 사항 및 분석은 다음과 같습니다. C ++에서 STL 세트의 기본 데이터 구조는 무엇입니까? 그리고 나는 그것들을 여기서 반복하지 않을 것입니다.
"BST"는 "테스트 된"을 의미 std::set
하고 "해시 맵"은 "테스트 된"을 의미 std::unordered_set
합니다. "힙"은 std::priority_queue
내가 분석 한 힙 : 이진 검색 트리 (BST)입니다.
빠른 요약으로 :
그래프는 이러한 조건에서 해시 맵 삽입이 100k 개가 넘는 항목이있을 때 항상 훨씬 빠르며 항목 수가 증가함에 따라 차이가 커짐을 분명히 보여줍니다.
이 속도 향상의 비용은 효율적으로 순회 할 수 없다는 것입니다.
곡선은 순서 std::set
가 BST 기반이며 std::unordered_set
해시 맵 기반 임을 분명히 나타냅니다 . 참조 답변에서 GDB 단계를 통해 코드를 디버깅한다는 것을 추가로 확인했습니다.
map
vs에 대한 비슷한 질문 unordered_map
: 사소한 키의 경우 unorder_map보다 map을 사용하면 어떤 이점이 있습니까?
다른 형식으로 변환하려는 경우 관계를 맺는 것이 편리하다고 말하고 싶습니다.
액세스하는 것이 더 빠르지 만 인덱스를 작성하거나 액세스 할 때 사용되는 메모리 또는 인덱스를 빌드하는 시간이 더 클 수도 있습니다.