2015-01-14 3 views
5

C++ 세계에 이러한 속성이있는 컨테이너가 있습니까?std :: vector 및 std :: set 속성을 가진 컨테이너?

  • 요소는 독특하고
  • 는 랜덤 액세스 연산자를 제공하는 사용자 정의 비교기의 도움으로 정렬됩니다.

저는 현재 주문 컬렉션에 랜덤 액세스를 가질 수있을 수있는 std::copy(_set.begin(),_set.end(),std::back_inserter(_vec))을 나중에 std::set<C,COMPARATOR>에 내 데이터를 수집하고 있습니다. 그러나 크기는 수억 수억 개가 될 수도 있습니다.

+0

힙 도움이 되겠습니까? 총 주문은 없지만 최대 요소를 선택할 수 있습니다. – Quentin

+0

@Quentin 엄격한 주문은 필수적입니다 – Oncaphillis

+2

데이터 중간에 많은 삽입 및/또는 삭제 작업을 수행 할 예정입니까? 수용 가능한 솔루션에 큰 변화가있을 것입니다. 현재의 솔루션은 벡터에 직접 추가하고'std :: sort'를 실행함으로써 더 좋을 수 있습니다. 전반적으로 약간 더 빨라야합니다. –

답변

7

부스트가 옵션 인 경우 flat_set in the Containers library을 살펴보십시오.

flat_set의 인터페이스는 std::set의 그것과 동일하지만 std::vector처럼 임의 접근 반복자를 제공합니다 : 당신이 표준 라이브러리와 함께 붙어있는 경우

#include <boost/container/flat_set.hpp> 

[...] 

boost::container::flat_set<int> c; 
c.insert(1); 
c.insert(2); 
c.insert(3); 
c.insert(4); 

// unfortunately, no operator[] on the container itself, 
// but the iterator is random access 
int third_element = c.begin()[2]; 

,이 목적을 위해 분류 vector를 사용할 수 있습니다. 표준 라이브러리는 실제로 <algorithm> 헤더에 많은 알고리즘을 제공합니다.이 알고리즘을 사용하면 정렬 된 반복자 범위가있는 set으로 수행 할 수있는 모든 작업을 수행 할 수 있습니다.

+0

삽입/삭제를위한 성능을 살펴 봐야 할 것입니다. 그러나 이것이 그것이라고 생각합니다. 부스트는 확실히 옵션이다 – Oncaphillis

+1

랜덤 액세스 반복자를 제공하지만'operator []'는 제공하지 않는다? 그 이유가 무엇인지 궁금합니다. – Barry

+1

글쎄, 10^6 난수 인서트로 테스트 해봤는데 sth가 걸렸다. 140 초. a std :: insert 을 나중에 std :: vector 에 복사하여 1 초 미만으로 복사합니다. 초기화 후에 많은 삽입/삭제를 수행하지 않기 때문에 나는 내 해결책을 고수한다고 생각한다. 그러나 나는 아직도이 대답을 내 초기 질문에 대한 적절한 해결책으로 생각한다. – Oncaphillis

1

나는 알고 있습니다. 그러나 수억 개의 요소와 일부 액세스 권한을 사용하면 메모리 표현을 작고 연속적으로 만들 수 있으므로 컨테이너 클래스에 더 많은 요구 사항이 필요합니다.

나는 std::vector으로 가서 설명한 방법이나 다른 정렬 알고리즘을 사용합니다. 나중에 std::set이 필요하지 않으므로 메모리를 확보 할 수 있습니다.

1

표준 C++ 라이브러리에는 없습니다. 주문시 set/priority_queue이거나 임의 액세스의 경우 vector/deque입니다.

그러나 단순히 주문을 시행하는 vector 주위에 자신 만의 래퍼를 작성하는 것을 막을 수있는 방법은 없습니다. 그렇게 많은 코드가 아닙니다. 몇 가지 예제 함수 :

template <typename T, typename COMP = std::less<T>> 
class sorted_vec { 
    std::vector<T> vec_; 

public: 
    // random access 
    using iterator = typename std::vector<T>::iterator; 
    T& operator[](size_t idx) { return vec_[idx]; } 

    iterator begin() { return vec_.begin(); } 
    iterator end() { return vec_.end(); } 

    // insertion 
    void push(const T& val) { 
     vec_.insert(std::lower_bound(vec_.begin(), vec_.end(), COMP{}), 
        val); 
    } 
}; 
+0

나는 또한'const' 버전의'T & operator []'를 써서'const' 참조를 전달할 수 있습니다. – vsoftco

+0

@vsoftco이 기능은 철저한 기능 목록이 아닙니다 (예 :'const_iterator' 등은 없습니다) – Barry

관련 문제