2010-07-25 9 views
3

와 회원이 컨테이너 내가 unique_ptr s의 용기에 저장된 일부 데이터가 있다고 가정 :주문 STL

struct MyData { 
    int id; // a unique id for this particular instance 
    data some_data; // arbitrary additional data 
}; 

// ... 

std::vector<std::unique_ptr<MyData>> my_data_vec; 

my_data_vec의 순서가 중요합니다. 이제 가정 내가 MyDatas의 ID의 또 다른 벡터를 가지고 :

지금 요소가 my_data_ids에 의해 지정된 순서에 있는지 my_data_vec는 재 배열 할
std::vector<int> my_data_ids; 

. (unique_ptrstd::move()으로 이동 의미가 필요함을 잊지 마십시오.)

알고리즘을 효율적으로 구현하는 방법은 무엇이며, STL 알고리즘은이를 달성하는 데 도움이됩니까? 나는 std::sort 어떤 도움이 될 것을 볼 수 없습니다.

편집 : O (n) 메모리 공간을 사용할 수 있지만 (메모리가 너무 걱정되지는 않음) ID는 임의적입니다 (실제로는 임의로 생성됩니다).

+0

O (N) 공간을 사용할 수 있습니까? –

+0

'id'는 임의적입니까? 아니면 0 ... n-1입니까? – Thomas

+0

이 점에 답하기 위해 질문을 편집했습니다. – AshleysBrain

답변

3
  1. 색인에 ID를 my_data_ids에 매핑하는지도를 만듭니다.
  2. 해당 맵의 ID 색인을 기준으로 std::unique_ptr<MyData>을 비교하는 함수 개체를 만듭니다.
  3. 해당 기능 개체를 사용하여 my_data_vec을 정렬하려면 std::sort을 사용하십시오. 메모리가 부족하지만, 시간이 문제가되지 않는 경우

    // Beware, brain-compiled code ahead! 
    typedef std::vector<int> my_data_ids_type; 
    typedef std::map<int,my_data_ids_type::size_type> my_data_ids_map_type; 
    
    class my_id_comparator : public std::binary_function< bool 
                    , std::unique_ptr<MyData> 
                    , std::unique_ptr<MyData> > { 
    public: 
        my_id_comparator(const my_data_ids_map_type& my_data_ids_map) 
        : my_data_ids_map_(my_data_ids_map) {} 
    
        bool operator()(const std::unique_ptr<MyData>& lhs 
           , const std::unique_ptr<MyData>& rhs) const 
        { 
        my_data_ids_map_type::const_iterator it_lhs = my_data_ids_map_.find(lhs.id); 
        my_data_ids_map_type::const_iterator it_rhs = my_data_ids_map_.find(rhs.id); 
        if(it_lhs == my_data_ids_map_.end() || it_rhs == my_data_ids_map_.end()) 
         throw "dammit!"; // whatever 
        return it_lhs->second < it_rhs->second; 
        } 
    private 
        my_data_ids_map_type& my_data_ids_map_; 
    }; 
    
    //... 
    
    my_data_ids_map_type my_data_ids_map; 
    // ... 
    // populate my_data_ids_map with the IDs and their indexes from my_data_ids 
    // ... 
    std::sort(my_data_vec.begin(), my_data_vec.end(), my_id_comparator(my_data_ids_map)); 
    

    , 당신은 멀리지도 할 각각의 비교를 위해 my_data_ids 벡터의 ID를 검색 할 수 있습니다 :

다음은이의 스케치입니다. 그러나 비교 당 두 개의 선형으로 복잡한 연산이 상당히 비싸기 때문에 이 실제로는이되어야합니다.

+1

이것은 아주 좋은 해결책입니다, 감사합니다! 'sort'가 적용될 수 있다고 생각하지 않았지만 당신이 나에게 틀 렸음을 증명했습니다 :) (btw는 C++ 0x를 사용했기 때문에 람다를 사용하여 조금 깔끔하게했습니다.) – AshleysBrain

+0

@James : 저는 아닙니다. 'std :: exception'을 던지는 것은이 장소에서 옳다. 문제가 제시된 방식으로, 각 ID에 대해 'my_data_ids'에 __must__ 항목이있는 것처럼 보입니다. 그렇다면 실패는 사전 조건이 유지되지 않음을 나타낼 것이기 때문에 아마 그 대신 어설 션이어야합니다. 나는 그 문제에 대해 거의 알지 못하기 때문에 분명히 잘못한 것을했고 그 의견에 동행했다. 더 많은 고려가 필요하다는 것이 분명해지기를 희망했다. 하지만 네가 맞을 수도있어. _ "내가하는 것처럼하지 말아라."_ 일반적으로 잘 작동하지 않습니다. 너는 무엇을 제안 하는가? – sbi

+0

@sbi : 나는 그저 농담처럼 :-)을 의미했다. (그렇다면 나는 그것을 삭제하지 않았기 때문에 재미 없다고 생각했다.)이 시나리오에서 필자는 내 생각에 관해서는 logic_error 나 그로부터 파생 된 것을 던지는 경향이있다. –

0

왜 데이터를 STL 세트로 이동하지 않으시겠습니까? 비교 기능 만 구현하면 완벽하게 정렬 된 데이터 세트가 매우 빨리 완성됩니다.

+1

좋은 아이디어 -하지만 my_data_vec의 순서는 중요하고 임의적입니다. 주문 정보는 세트에 의해 손실됩니다. – AshleysBrain

+1

"왜 데이터를 STL 세트로 옮기려하지 않습니까?" 왜냐하면 그들은'my_data_ids '에 의해 지정된 순서가 아니기 때문이다. – sbi

0

map<int, unique_ptr<MyData>> (또는 multimap)을 사용하지 않으시겠습니까?